【问题标题】:R get rows based on multiple conditions - use dplyr and reshape2R 根据多个条件获取行 - 使用 dplyr 和 reshape2
【发布时间】:2015-01-29 15:08:55
【问题描述】:
df <- data.frame(
    exp=c(1,1,2,2),
  name=c("gene1", "gene2", "gene1", "gene2"),
    value=c(1,1,3,-1)
    )

在尝试习惯 dplyrreshape2时,我偶然发现了一种基于多个条件选择行的“简单”方法。如果我想在实验 1 中拥有那些具有valueabove 0 的基因(namevariable)(exp== 1)并且同时在实验 2 中拥有valuebelow 0;在 df 这将是“gene2”。当然必须有很多方法,例如每组条件(exp==1 & value > 0, and exp==2 and value

library(dplyr)    
inner_join(filter(df,exp == 1 & value > 0),filter(df,exp == 2 & value < 0), by= c("name"="name"))[[1]]

虽然这可行,但它看起来很不公平,我觉得这种条件过滤位于reshape2dplyr 的核心,但不知道如何做到这一点。有人可以在这里启发我吗?

【问题讨论】:

    标签: r conditional filtering dplyr reshape2


    【解决方案1】:

    filter 允许多个带逗号的参数,与select 相同。每个额外的条件都是一个 AND:

    group_by(df, name) %&gt;% filter(value[exp == 1] &gt; 0, value[exp == 2] &lt; 0)

    来自官方文档:https://cran.rstudio.com/web/packages/dplyr/vignettes/introduction.html

    那里显示的例子是:

    • flights[flights$month == 1 &amp; flights$day == 1, ] 在基础 R

    • filter(flights, month == 1, day == 1) 在 dplyr 中。

    【讨论】:

      【解决方案2】:

      另一个 dplyr 选项是:

      group_by(df, name) %>% filter(value[exp == 1] > 0 & value[exp == 2] < 0)
      
      #Source: local data frame [2 x 3]
      #Groups: name
      #
      #  exp  name value
      #1   1 gene2     1
      #2   2 gene2    -1
      

      【讨论】:

        【解决方案3】:

        可能这比您自己的解决方案更令人费解,但我认为它具有“dplyr”的感觉:

        df %>% 
            filter((exp == 1 & value > 0) | (exp == 2 & value < 0)) %>% 
            group_by(name) %>% 
            filter(length(unique(exp)) == 2) %>% 
            select(name) %>% 
            unique()
        
        #Source: local data frame [1 x 1]
        #Groups: name
        
        #   name
        #1 gene2
        

        【讨论】:

          【解决方案4】:

          想到的另一种选择是将数据转换为“宽”格式,然后进行过滤。

          这是一个使用“data.table”的示例(为了方便复合语句):

          library(data.table)
          dcast.data.table(as.data.table(df), name ~ exp)[`1` > 0 & `2` < 0]
          #     name 1  2
          # 1: gene2 1 -1
          

          类似地,“dplyr”和“tidyr”:

          library(dplyr)
          library(tidyr)
          df %>% 
            spread(exp, value) %>% 
            filter(`1` > 0 & `2` < 0)
          

          【讨论】:

          • 这个解决方案既简单又出色!谢谢!我让我学到了很多东西!顺便问一下,我可以问你一个问题吗?为什么新的列名要表示为`1`而不是'1'"1"?谢谢!
          • @FranciscoRodriguezAlgarra,说实话,我没有尝试其他人。一般来说,在处理有问题的变量名时,我会直接使用反引号,这也是在?Quote的帮助页面中推荐的。
          • @Ananda Mahto,您能否解释一下您对反引号的评论 - 变量名称是否可能有问题(因为它们有名称“1”和“2”)?
          • @user3375672,是的。 dcast 不会尝试使名称在语法上有效,因此在这种情况下,我们最终会得到名为“1”和“2”的列。由于它们在语法上无效,因此需要以某种方式引用它们。
          猜你喜欢
          • 2018-07-10
          • 2018-01-21
          • 2023-03-13
          • 2021-07-06
          • 2021-12-04
          • 1970-01-01
          • 2019-01-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多