R-按组子集

时间:2018-08-10 11:04:48

标签: r

我有以下data.frame:

Name    Expr    FC  FDR
probe1  gene1   1   1.5 0.005
probe2  gene2   1   1.3 0.02
probe3  gene1   2   1.2 0.000003
probe4  gene4   3   1.8 0.5
probe5  gene5   4   1.9 0.00008
probe6  gene2   5   1.3 0.03
probe7  gene4   3   1.2 0.0001
probe8  gene8   10  1.3 0.01
probe9  gene8   11  1.8 0.01

有许多探针代表同一基因。 我想基于FDR为每个基因只选择1个探针,即为每个基因选择FDR最小的探针。如果同一基因的2个探针具有相同的FDR,则随机选择一个。 我想将以下data.frame作为输出:

Name    Expr    FC  FDR
probe3  gene1   2   1.2 0.000003
probe4  gene5   4   1.9 0.00008
probe6  gene4   3   1.2 0.0001
probe2  gene2   1   1.3 0.02
probe8  gene8   10  1.3 0.01

预先感谢您的帮助!

4 个答案:

答案 0 :(得分:3)

使用dplyr,您可以做到:

df <- read.table(text = "
Name    Expr    FC   FDR
probe1  gene1   1   1.5 0.005
probe2  gene2   1   1.3 0.02
probe3  gene1   2   1.2 0.000003
probe4  gene4   3   1.8 0.5
probe5  gene5   4   1.9 0.00008
probe6  gene2   5   1.3 0.03
probe7  gene4   3   1.2 0.0001
probe8  gene8   10  1.3 0.01
probe9  gene8   11  1.8 0.01", h= T)

library(dplyr)
df %>% 
  group_by(Name) %>% 
  slice(which.min(FDR))

在Andre Elrico评论后更新:

如果要为最小FDR连接而对1行进行采样,可以执行此操作。

df %>% 
  group_by(Name) %>% 
  filter(FDR == min(FDR)) %>% 
  sample_n(1)

答案 1 :(得分:2)

(我认为此处的否决票有些苛刻:OP提供了示例数据和清晰的问题陈述。)

有很多方法可以实现这一目标,我鼓励您花一些时间在此处研究类似的问题。通常,您将学到很多有关汇总/汇总数据的知识。

这是使用split

的基本R可能性
do.call(rbind, lapply(split(df, df$Name), function(df) df[which.min(df$FDR), ]))
#       Name Expr  FC   FDR
#gene1 gene1    2 1.2 3e-06
#gene2 gene2    1 1.3 2e-02
#gene4 gene4    3 1.2 1e-04
#gene5 gene5    4 1.9 8e-05
#gene8 gene8   10 1.3 1e-02

或使用by(感谢@RuiBarradas)

do.call(rbind, by(df, df$Name, function(x) x[which.min(x$FDR), ]))
   #    Name Expr  FC   FDR
#gene1 gene1    2 1.2 3e-06
#gene2 gene2    1 1.3 2e-02
#gene4 gene4    3 1.2 1e-04
#gene5 gene5    4 1.9 8e-05
#gene8 gene8   10 1.3 1e-02

样本数据

df <- read.table(text =
    "Name    Expr    FC  FDR
probe1  gene1   1   1.5 0.005
probe2  gene2   1   1.3 0.02
probe3  gene1   2   1.2 0.000003
probe4  gene4   3   1.8 0.5
probe5  gene5   4   1.9 0.00008
probe6  gene2   5   1.3 0.03
probe7  gene4   3   1.2 0.0001
probe8  gene8   10  1.3 0.01
probe9  gene8   11  1.8 0.01", header = T)

答案 2 :(得分:1)

一种data.table解决方案:

library(data.table)
setDT(df)

df[order(FDR), .SD[1], Name]
    Expr   Name FC FC2   FDR
1: gene1 probe3  2 1.2 3e-06
2: gene5 probe5  4 1.9 8e-05
3: gene4 probe7  3 1.2 1e-04
4: gene8 probe8 10 1.3 1e-02
5: gene2 probe2  1 1.3 2e-02

位置:

df <- data.frame(
  Name = paste0("gene", c(1, 2, 4, 5, 8))[c(1, 2, 1, 3, 4, 2, 3, 5, 5)], 
  Expr = c(1L, 1L, 2L, 3L, 4L, 5L, 3L, 10L, 11L), 
  FC = c(1.5, 1.3, 1.2, 1.8, 1.9, 1.3, 1.2, 1.3, 1.8), 
  FDR = c(0.005, 0.02, 3e-06, 0.5, 8e-05, 0.03, 1e-04, 0.01, 0.01)
) 

答案 3 :(得分:0)

这是avebase R的一个选项。这也将给出具有联系的行

df[with(df, ave(FDR, Name, FUN = min) == FDR),]