【问题标题】:Filter rows which has at least one of particular values过滤具有至少一个特定值的行
【发布时间】:2018-12-08 14:33:40
【问题描述】:

我有一个这样的数据框。

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

我想获取三列TourOrderMachine 至少包含一个DEG 的行。

结果应该是:

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

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

【问题讨论】:

  • 请与 dput() 共享 df

标签: r dataframe filter conditional-statements any


【解决方案1】:
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 将返回一个布尔矩阵,其中包含每个单元格的匹配项。
  • 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")

【讨论】:

  • 不产生所需的输出,作为第二行,因为它们没有对公司进行过滤
【解决方案2】:

另一种选择:

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

【讨论】:

    【解决方案3】:

    另一个使用filter_attidyverse方法

    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 &gt;= 1.0

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

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

    【讨论】:

      【解决方案4】:

      您可以通过lapply 在列上检查匹配项,然后使用Reduce 使用|(或)选择是否有任何匹配项。

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

      【讨论】:

        【解决方案5】:

        使用基础 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
        

        【讨论】:

          猜你喜欢
          • 2021-08-07
          • 2017-04-11
          • 1970-01-01
          • 1970-01-01
          • 2011-11-23
          • 1970-01-01
          • 1970-01-01
          • 2020-05-28
          • 2014-03-28
          相关资源
          最近更新 更多