代码之家  ›  专栏  ›  技术社区  ›  nak5120

如果名为的列包含部分值,则保留行

  •  1
  • nak5120  · 技术社区  · 7 年前

    我有一个数据集:

    Camp1    Ade2    Camp3    Ade4    
       dA       1       eB       2
       dB       4       uC       8
       gB       3       NA      NA
    

    如果名称中包含“camp”的列名称不包含值“a”、“b”或na,如何对该数据集进行子集,排除这些行。

    我知道如何精确匹配,但不是部分匹配。

    cols = grepl("Camp", names(df))
    rows = rowSums(df[, cols] == "A" | 
    df[, cols] == "B" |
    is.na(df[, cols])) == sum(cols)
    df<-df[rows, ]
    

    如何进行等价但有部分匹配?

    预期输出:

    Camp1    Ade2    Camp3    Ade4    
       dA       1       eB       2
       gB       3       NA      NA
    
    3 回复  |  直到 7 年前
        1
  •  1
  •   tmfmnk    7 年前

    使用Base R,您可以尝试:

    df_cols <- df[, grepl("Camp", names(df))]
    df[apply(df_cols, 1, function(x) all(grepl("A|B", x) | is.na(x))), ]
    
      Camp1 Ade2 Camp3 Ade4
    1    dA    1    eB    2
    3    gB    3  <NA>   NA
    

    在第一步中,它标识在其名称中包含“camp”的列,然后根据给定条件对数据进行子集。

        2
  •  2
  •   acylam    7 年前

    我们可以使用 filter_at dplyr . 使用 starts_with helper函数,我们将过滤器应用于以 'Camp' . 在这些列中,我们筛选 all_vars 包含 A B NA :

    library(dplyr)
    
    df %>%
      filter_at(vars(starts_with("Camp")), all_vars(grepl('A|B', .) | is.na(.)))
    

    输出:

      Camp1 Ade2 Camp3 Ade4
    1    dA    1    eB    2
    2    gB    3  <NA>   NA
    

    数据:

    df <- structure(list(Camp1 = structure(1:3, .Label = c("dA", "dB", 
    "gB"), class = "factor"), Ade2 = c(1L, 4L, 3L), Camp3 = structure(c(1L, 
    2L, NA), .Label = c("eB", "uC"), class = "factor"), Ade4 = c(2L, 
    8L, NA)), class = "data.frame", row.names = c(NA, -3L))
    
        3
  •  1
  •   Curt F.    7 年前

    这里有一个tidyverse风格的解决方案。

    使用 filter_at :

    my_df %>%
        filter_at(vars(matches('Camp')), all_vars(is.na(.) | str_detect(., 'A|B')))
    

    在这里, vars(matches('Camp')) 指示筛选名称中包含字符串的列 Camp all_vars(...) 说只保留行 全部的 列[与“camp”匹配]符合指定的条件。

    你需要这么做 require(tidyverse) require(stringr) 为了这个工作。