过滤至少具有一个特定值的行

Filter rows which has at least one of particular values

我有一个这样的数据框。

df
    Tour    Order   Machine    Company
[1]    A        D         D          B
[2]    B        B         A          G
[3]    A        E         B          A
[4]    C        B         C          B
[5]    A        G         G          C

我想获取三列 TourOrder Machine 中至少包含一个 D E 或 [=18= 的行].

结果应该是:

    Tour    Order   Machine    Company
[1]    A        D         D          B
[3]    A        E         B          A
[5]    A        G         G          C

我的尝试:

df %>%
    filter(any(c(Tour, Order, Machine) %in% c('D', 'E', 'G')))

但它没有正确过滤(返回所有行)。有人可以帮我吗?

ind <- apply(sapply(df1[c("Tour","Order","Machine")],`%in%`,c('D', 'E', 'G')),1,any)
df1[ind,]
#   Tour Order Machine Company
# 1    A     D       D       B
# 3    A     E       B       A
# 5    A     G       G       C
  • sapply 将 return 包含每个单元格匹配项的布尔矩阵。
  • apply 将检查其中是否有 TRUE,这意味着您要保留行
  • 我们过滤输入

dplyr 版本:

df1 %>%
  filter_at(c("Tour","Order","Machine"),any_vars(.%in% c('D', 'E', 'G')))
#   Tour Order Machine Company
# 1    A     D       D       B
# 2    A     E       B       A
# 3    A     G       G       C

数据

df1 <- read.table(header=TRUE,stringsAsFactors=FALSE,text="
 Tour    Order   Machine    Company
    A        D         D          B
    B        B         A          G
    A        E         B          A
    C        B         C          B
    A        G         G          C")

另一个选项:

df[rowSums(sapply(df[-4], '%in%', c('D', 'E', 'G'))) > 0,]

结果:

  Tour Order Machine Company
1    A     D       D       B
3    A     E       B       A
5    A     G       G       C

对于 dplyr 你应该添加 rowwise():

df %>%
  rowwise() %>% 
  filter(any(c(Tour, Order, Machine) %in% c('D', 'E', 'G')))

另一种 tidyverse 方法使用 filter_at

df %>% filter_at(vars(-Company), any_vars(. %in% c("D", "E", "G")))
#  Tour Order Machine Company
#1    A     D       D       B
#2    A     E       B       A
#3    A     G       G       C

更新 dplyr >= 1.0

filter_atany_vars 已被 if_any 取代,以便更简洁

df %>% filter(if_any(-Company, `%in%`, c("D", "E", "G")))

您可以 lapply 在列上检查匹配项,然后 Reduce 使用 | (或者) select 如果有任何匹配项。

df[Reduce('|', lapply(df[-4], '%in%', c('D', 'E', 'G'))),]

使用基数 R:

df1[grepl("[DEG]",do.call(paste,df1[-4])),]# YOU CAN USE "D|E|G"

  Tour Order Machine Company
1    A     D       D       B
3    A     E       B       A
5    A     G       G       C