提取“ n”行,样本间变化最小

时间:2018-07-27 14:29:22

标签: r dataframe dplyr tidyverse

示例数据框:

a = c(1,2,3,4,5,6)
b = c(1,1.1,1.2,1.3,1.4,1.5)
c = c(2,4,6,7,9,20)
d = c(1,1,1,1.2,1,1.3)
e = c(6,9,100,20,52,61)
gene = c("gene1","gene2","gene3","gene4","gene5","gene6")
df = data.frame(gene,a,b,c,d,e)

嗨, 从数据帧中,我想提取“ n”个行/基因(例如2个),它们在整个数据集中最稳定,即样本中强度的变化最小。我怎样才能做到这一点? 非常感谢

3 个答案:

答案 0 :(得分:3)

1)基本R 这仅使用基本R:

n <- 3
df[head(order(apply(df[-1], 1, sd)), n), ]

给予:

   gene a   b c   d  e
1 gene1 1 1.0 2 1.0  6
2 gene2 2 1.1 4 1.0  9
4 gene4 4 1.3 7 1.2 20

2)dplyr / apply (使用dplyr / apply)或使用dplyr,我们有以下内容。

library(dplyr)

n <- 3
df %>%
   arrange(select(., -gene) %>% apply(1, sd)) %>%
   top_n(-n)

3)dplyr / rowwise 或另一种dplyr解决方案,该解决方案使用rowwise。请注意,do中的点表示列表中的当前行,而{...}中的点表示其所在表达式的输入。如果要保留行号,请省略select(-sd)行。 sd列。

library(dplyr)

n <- 3
df %>% 
   rowwise %>% 
   do(as.data.frame(.) %>% { mutate(., sd = select(., -gene) %>% sd(.))}) %>%
   ungroup %>%
   arrange(sd) %>%
   select(-sd) %>%
   top_n(-n)

4)dplyr / purrr 与(2)相同,除了它使用来自purrr的pmap_dbl而不是apply

library(dplyr)
library(purr)

n <- 3
df %>%
   arrange(select(., -gene) %>% pmap_dbl(~ sd(c(...)))) %>%
   top_n(-n)

答案 1 :(得分:2)

这是使用rowSds中的matrixStats的选项

library(matrixStats)
n <- 3
df[order(rowSds(as.matrix(df[-1])))[seq_len(n)],]
#   gene a   b c   d  e
#1 gene1 1 1.0 2 1.0  6
#2 gene2 2 1.1 4 1.0  9
#4 gene4 4 1.3 7 1.2 20

或使用tidyverse

library(tidyverse)
df %>%
   arrange(pmap_dbl(.[-1], ~ sd(c(...)))) %>% 
   slice(seq_len(n))
#   gene a   b c   d  e
#1 gene1 1 1.0 2 1.0  6
#2 gene2 2 1.1 4 1.0  9
#3 gene4 4 1.3 7 1.2 20

或与rowSds

df %>%
     arrange(rowSds(as.matrix(.[-1]))) %>%
     slice(seq_len(n))
#   gene a   b c   d  e
#1 gene1 1 1.0 2 1.0  6
#2 gene2 2 1.1 4 1.0  9
#3 gene4 4 1.3 7 1.2 20

或与data.table

library(data.table)
setDT(df)[df[, order(rowSds(as.matrix(.SD)))[seq_len(n)], .SDcols = -1]]
#    gene a   b c   d  e
#1: gene1 1 1.0 2 1.0  6
#2: gene2 2 1.1 4 1.0  9
#3: gene4 4 1.3 7 1.2 20

答案 2 :(得分:1)

使用data.table

library(data.table)

# Helper function
meanad <- function(x) {
  sum(abs(x-mean(x)))/length(x)
}

k <- 3
topgenes <- setDT(df)[, meanad := meanad(unlist(.SD)), by = gene
                      ][order(meanad)
                        ][, as.character(head(gene, k))
                          ]

df[gene %in% topgenes]
    gene a   b c   d  e   meanad
1: gene1 1 1.0 2 1.0  6 1.304444
2: gene2 2 1.1 4 1.0  9 2.159556
3: gene4 4 1.3 7 1.2 20 4.673333