【问题标题】:R dplyr filtering data with values greater than +N and lesser than -N : abs() function?R dplyr 过滤值大于 +N 且小于 -N 的数据:abs() 函数?
【发布时间】:2019-07-22 01:00:19
【问题描述】:

我正在使用 R 中的 dplyr 包来过滤我的基因表达数据。我已经计算了倍数变化,并希望过滤至少一个样本(列)的值大于 +0.584963 或小于 -0.584963 的基因(行)。示例数据:

       X SAMPLE_1_FC SAMPLE_2_FC SAMPLE_3_FC SAMPLE_4_FC SAMPLE_5_FC
GENE_1      0.6780      0.4050      0.8870      0.3300      0.2230
GENE_2      0.2340     -0.6670      0.0020      0.1240      0.3560
GENE_3      0.0170      0.1560      0.1120      0.0080     -0.1230
GENE_4     -0.0944     -0.1372     -0.1800     -0.2228     -0.2656
GENE_5     -0.8080     -0.7800     -0.5560      0.0340      0.4450
GENE_6      0.2091      0.1106      0.0121     -0.0864     -0.1849
GENE_7      0.5980      0.7680      0.9970      0.4670     -0.7760

我目前正在使用以下脚本

det.cols<- colnames(my.data)[which(grepl("fc",tolower(colnames(my.data))))]
filt <- gsub(","," | ",toString(paste("`",det.cols,"`",">abs(0.584963)", sep = "")))
my.datasub<- my.data %>% filter_(filt)

但这只会返回大于 +0.584963 的基因,而不是负数。在示例的情况下,我想要的是一个包含基因 1、2、5 和 7 的子集列表。但它只给了我基因 1 和 7。我该如何更改?

我希望答案是这种格式:

 X SAMPLE_1_FC SAMPLE_2_FC SAMPLE_3_FC SAMPLE_4_FC SAMPLE_5_FC
GENE_1      0.6780      0.4050      0.8870      0.3300      0.2230
GENE_2      0.2340     -0.6670      0.0020      0.1240      0.3560
GENE_5     -0.8080     -0.7800     -0.5560      0.0340      0.4450
GENE_7      0.5980      0.7680      0.9970      0.4670     -0.7760

谢谢。

【问题讨论】:

  • 请提供一些示例数据,以作为完全可重现的示例。谢谢!
  • 谢谢叶亚瑟。我已经编辑了这个问题。希望对您有所帮助。
  • 哦,我终于在您的代码中发现了小错误。我在下面的答案中修复了它。
  • 看起来自定义过滤器代码来自stackoverflow.com/questions/43981187/… - 下次链接到源材料时会有所帮助

标签: r dplyr


【解决方案1】:

长话短说,您的代码中的 abs() 位置错误。

我在这里修好了:

det.cols<- colnames(my.data)[which(grepl("fc",tolower(colnames(my.data))))]
filt <- gsub(","," | ",toString(paste("abs(`",det.cols,"`)",">0.584963", sep = "")))
my.datasub<- my.data %>% filter_(filt)

为了进一步提高灵活性,@ha_pu 提供了一个很棒的filter_at 解决方案,该解决方案基于我之前的解决方案(在我发现您的代码中的错误之前)。

【讨论】:

    【解决方案2】:

    这是一个灵活的样本和数据行数的解决方案。它涉及将数据转换为长格式,然后过滤基因和特定样本。我在 50k 个基因和 35 个样本上对其进行了测试,它在

    library(tidyverse)
    
    # set up sample data with 50000 rows
    mydata <- data.frame(stringsAsFactors=FALSE,
                         X = c("GENE_1", "GENE_2", "GENE_3", "GENE_4", "GENE_5", "GENE_6", "GENE_7", 1:50000),
                         SAMPLE_1_FC = c(0.678, 0.234, 0.017, -0.0944, -0.808, 0.2091, 0.598, rnorm(50000, 0, 1)),
                         SAMPLE_2_FC = c(0.405, -0.667, 0.156, -0.1372, -0.78, 0.1106, 0.768, rnorm(50000, 0, 1)),
                         SAMPLE_3_FC = c(0.887, 0.002, 0.112, -0.18, -0.556, 0.0121, 0.997, rnorm(50000, 0, 1)),
                         SAMPLE_4_FC = c(0.33, 0.124, 0.008, -0.2228, 0.034, -0.0864, 0.467, rnorm(50000, 0, 1)),
                         SAMPLE_5_FC = c(0.223, 0.356, -0.123, -0.2656, 0.445, -0.1849, -0.776, rnorm(50000, 0, 1)))
    
    # duplicate 30 more columns
    mydata2 <- bind_cols(mydata, mydata[2:6], mydata[2:6], mydata[2:6], mydata[2:6], mydata[2:6], mydata[2:6])
    
    (mydata3 <- mydata2 %>% gather(key = "sample_num", value = "fc", 2:length(mydata)) %>%
      filter(fc > 0.584963 | fc < -0.584963) %>%
      select(X) %>%
      arrange(desc(X)) %>%
      unique() %>%
      head())
    #>         X
    #> 1  GENE_7
    #> 5  GENE_5
    #> 7  GENE_2
    #> 8  GENE_1
    #> 10   9999
    #> 14   9998
    

    reprex package (v0.2.1) 于 2019 年 3 月 1 日创建

    【讨论】:

    • 这给出了结果,但结果的格式仍然难以处理。我期待一个具有相同列但只是基因缩小的表的结果。我这样做是为了缩小 pval0.584963。
    • 现在代码会生成一个包含所有基因名称的列。你需要/期待什么?
    • 我刚刚用预期的格式重新编辑了这个问题,因为我不确定如何将它放在评论中
    【解决方案3】:

    使用dplyr 中的filter_at 可能是一种更灵活的方法...

    # set up sample data with 50000 rows [as proposed by Arthur Yip above]
    mydata <- tibble(X = c("GENE_1", "GENE_2", "GENE_3", "GENE_4", "GENE_5", "GENE_6", "GENE_7", 1:50000),
                         SAMPLE_1_FC = c(0.678, 0.234, 0.017, -0.0944, -0.808, 0.2091, 0.598, rnorm(50000, 0, 1)),
                         SAMPLE_2_FC = c(0.405, -0.667, 0.156, -0.1372, -0.78, 0.1106, 0.768, rnorm(50000, 0, 1)),
                         SAMPLE_3_FC = c(0.887, 0.002, 0.112, -0.18, -0.556, 0.0121, 0.997, rnorm(50000, 0, 1)),
                         SAMPLE_4_FC = c(0.33, 0.124, 0.008, -0.2228, 0.034, -0.0864, 0.467, rnorm(50000, 0, 1)),
                         SAMPLE_5_FC = c(0.223, 0.356, -0.123, -0.2656, 0.445, -0.1849, -0.776, rnorm(50000, 0, 1)))
    
    # duplicate 30 more columns [as proposed by Arthur Yip above]
    mydata2 <- bind_cols(mydata, mydata[2:6], mydata[2:6], mydata[2:6], mydata[2:6], mydata[2:6], mydata[2:6])
    
    mydata2 %>%
      filter_at(vars(contains("fc")), .vars_predicate =  any_vars(abs(.) > 0.584963))
    

    vars() 中,您可以定义要应用过滤的变量列表。在.vars_predicate 之后可以定义过滤条件(any_vars 等于|all_vars 等于&amp;)。

    【讨论】:

    • 感谢 ha_pu 的回答,抱歉我不清楚这个问题。我现在已经编辑了我的问题并添加了一个示例数据。我有多个列,并且想要提取其中至少一个列具有 >0.584963 或
    • 感谢您的澄清,我已相应地调整了我的回复。
    • Sayan 想要带有“fc”的列,所以我们可以说 filter_at(vars(contains("fc")), ... 这基本上是 grepl 和自定义 filt 的一个更简单的版本在开场白中。
    • 根据您的需要,您还可以在 vars() 表达式中使用matches(),允许使用正则表达式,让您的变量选择更加灵活...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-30
    • 2012-01-06
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 2023-01-25
    相关资源
    最近更新 更多