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

时间:2019-02-11 19:17:43

标签: r grepl

我有一个数据集:

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 个答案:

答案 0 :(得分:2)

我们可以使用filter_at中的dplyr。使用starts_with帮助函数,我们将过滤器应用于以'Camp'开头的每一列。在这些列上,我们对all_vars包含ABNA的行进行过滤:

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))

答案 1 :(得分:1)

这是一种整洁的解决方案。

使用filter_at

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

在这里,vars(matches('Camp'))表示过滤名称包含字符串Camp的列,而all_vars(...)表示仅保留 all 列中的行[匹配“营”]符合指定条件。

您需要先进行require(tidyverse)require(stringr)的操作。

答案 2 :(得分:1)

使用基数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”的列,然后根据给定条件对数据进行子集化。