【问题标题】:How to select individual rows from duplicates based on the highest median in R?如何根据 R 中的最高中位数从重复项中选择单个行?
【发布时间】:2015-08-03 17:19:01
【问题描述】:

我有一个包含如下基因表达数据的数据框:

row.names     symbol     Sample1     Sample2     Sample3     Sample4
Probe1        Gene1      1.5         2.8         1.8         3.2
Probe2        Gene2      2.7         4.5         3.2         5.1
Probe3        Gene3      1.1         4.7         2.3         5.3
Probe4        Gene2      1.2         0.9         0.8         1.1
Probe5        Gene1      3.1         6.1         6.2         4.2

我想对数据进行子集化,以便只保留独特的基因,并且在每种情况下都将保留具有最高中位数的探针,即上面的数据将变为以下内容:

row.names     symbol     Sample1     Sample2     Sample3     Sample4
Probe2        Gene2      2.7         4.5         3.2         5.1
Probe3        Gene3      1.1         4.7         2.3         5.3
Probe5        Gene1      3.1         6.1         6.2         4.2

数据框有约 40,000 个单独的探针和约 100 个样本。

有人知道 R 中哪些命令适合该任务吗?

【问题讨论】:

  • 你应该在你的问题中添加一个可重复的例子。
  • @MikeRSpencer 你是什么意思?
  • 我喜欢看到生成的虚拟数据来帮助提问者(和其他人)完成答案,所以在这种情况下类似于:df = data.frame(symbol=rep(c("Gene1" , "Gene2", "Gene3"), each=3), Sample1=rnorm(9), etc.) 它保存了那些回答问题的人。

标签: r


【解决方案1】:

我不会按行计算中位数,而是使用 matrixStats 包中的矢量化 rowMedians 函数。然后,我将按结果重新排序并使用 data.table 包选择唯一条目

library(data.table)
library(matrixStats)
df$Medians <- rowMedians(as.matrix(df[-(1:2)]))
unique(setDT(df)[order(-Medians)], by = "symbol")
#    row.names symbol Sample1 Sample2 Sample3 Sample4 Medians
# 1:    Probe5  Gene1     3.1     6.1     6.2     4.2    5.15
# 2:    Probe2  Gene2     2.7     4.5     3.2     5.1    3.85
# 3:    Probe3  Gene3     1.1     4.7     2.3     5.3    3.50

一些基准测试

library(data.table)
library(matrixStats)
library(dplyr)

set.seed(123)
bigdf <- data.frame(A = paste0("Probe", 1:1e5),
                    symbol = paste0("Gene", sample(1e2, 1e5, replace = TRUE)),
                    matrix(sample(1e2, 1e6, replace = TRUE), ncol = 100))
bigdf2 <- copy(bigdf)
bigdf3 <- copy(bigdf2)

system.time({
  bigdf$Medians <- rowMedians(as.matrix(bigdf[-(1:2)]))
  unique(setDT(bigdf)[order(-Medians)], by = "symbol")
  })

# user  system elapsed 
# 0.22    0.05    0.26 

system.time(setDT(bigdf2)[,.SD[which.max(apply(.SD[,-(1:2), with = FALSE], 1, median)),], by = symbol])
# user  system elapsed 
# 5.17    0.01    5.33 
system.time({
              bigdf3$medianCol <- apply(bigdf3[-(1:2)],1,FUN = median)
              grouped_df <- group_by(bigdf3,symbol)
              filtered_df <- filter(grouped_df, medianCol == max(medianCol))
})
# user  system elapsed 
# 5.15    0.00    5.15 

【讨论】:

  • 不知道这个功能!这个包看起来很有趣。
  • 是的,你甚至可以忽略转换为矩阵的缺点,因为apply 完全一样。
【解决方案2】:

或者使用 dplyr:

library(dplyr)
df$medianCol <- apply(df[,2:5],1,FUN = median)
grouped_df <- group_by(df,symbol)
filtered_df <- filter(grouped_df, medianCol == max(medianCol))
filtered_df$medianCol <- NULL

【讨论】:

    猜你喜欢
    • 2020-09-22
    • 1970-01-01
    • 2012-02-02
    • 2021-02-06
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 2019-02-25
    相关资源
    最近更新 更多