将具有相同名称的数据分组并应用功能

时间:2013-10-02 09:14:11

标签: r

我有这样的矩阵: 我想对它们具有相同名称的列进行分组,并将函数应用于矩阵的行。

>data

      A  A  A  B  B  C
gene1 1  6 11 16 21 26
gene2 2  7 12 17 22 27
gene3 3  8 13 18 23 28
gene4 4  9 14 19 24 29
gene5 5 10 15 20 25 30

基本上,我希望将具有相同名称的列(例如A)添加到组1 ,将B添加到组2 ,...以及之后我计算所有组的每个基因的T检验。 任何人都可以帮我,我该怎么做?第一步:分组,然后应用T检验,返回不同组之间每个基因的T分数。

1 个答案:

答案 0 :(得分:4)

OP没有在他们的输出中提到他们想要的形式,但我完全用一个可能的解决方案来更新这个答案。

首先,使用一些可重现的样本数据(实际上可以与t.test一起使用)。

set.seed(1)
mymat <- matrix(sample(100, 40, replace = TRUE), 
                ncol = 8, dimnames = list(
                  paste("gene", 1:5, sep = ""), 
                  c("A", "A", "A", "B", "B", "B", "C", "C")))
mymat
#        A  A  A   B  B  B  C  C
# gene1 27 90 21  50 94 39 49 67
# gene2 38 95 18  72 22  2 60 80
# gene3 58 67 69 100 66 39 50 11
# gene4 91 63 39  39 13 87 19 73
# gene5 21  7 77  78 27 35 83 42

我已将所有努力工作留给了combn功能。在combn函数中,我利用FUN参数添加了一个函数,该函数每行创建一个t.test“统计量”的向量(我假设一个基因每行)。我还在结果向量中添加了attribute,以提醒我们在计算统计数据时使用了哪些列。

temp <- combn(unique(colnames(mymat)), 2, FUN = function(x) {
  out <- vector(length = nrow(mymat))
  for (i in sequence(nrow(mymat))) {
    out[i] <- t.test(mymat[i, colnames(mymat) %in% x[1]], 
           mymat[i, colnames(mymat) %in% x[2]])$statistic
  }
  attr(out, "NAME") <- paste(x, collapse = "")
  out
}, simplify = FALSE)

以上输出为list vectors。将其转换为matrix可能更方便。由于我们知道向量中的每个值代表一行,并且每个向量总体上代表一个列值组合(AB,AC或BC),因此我们可以将其用于生成dimnames的{​​{1}}

matrix

一些手动验证:

DimNames <- list(rownames(mymat), sapply(temp, attr, "NAME"))

final <- do.call(cbind, temp)
dimnames(final) <- DimNames
final
#               AB         AC           BC
# gene1 -0.5407966 -0.5035088  0.157386919
# gene2  0.5900350 -0.7822292 -1.645448267
# gene3 -0.2040539  1.7263502  1.438525163
# gene4  0.6825062  0.5933218  0.009627409
# gene5 -0.4384258 -0.9283003 -0.611226402

更新

基于@ EDi的回答,这是另一种方法。它利用“reshape2”中的## Should be the same as final[1, "AC"] t.test(mymat[1, colnames(mymat) %in% "A"], mymat[1, colnames(mymat) %in% "C"])$statistic # t # -0.5035088 ## Should be the same as final[5, "BC"] t.test(mymat[5, colnames(mymat) %in% "B"], mymat[5, colnames(mymat) %in% "C"])$statistic # t # -0.6112264 ## Should be the same as final[3, "AB"] t.test(mymat[3, colnames(mymat) %in% "A"], mymat[3, colnames(mymat) %in% "B"])$statistic # t # -0.2040539 将数据转换为“长”格式。从那里开始,就像以前一样,这是非常简单的子集工作,以获得你想要的东西。那里的输出与纯melt方法采用的方法相对应,但值是相同的。

combn

第一个选项要快得多,至少在这个较小的数据集上是这样的:

library(reshape2)
mymatL <- melt(mymat)

byGene <- split(mymatL, mymatL$Var1)
RowNames <- combn(unique(as.character(mymatL$Var2)), 2, 
                  FUN = paste, collapse = "")

out <- sapply(byGene, function(combos) {
  combn(unique(as.character(mymatL$Var2)), 2, FUN = function(x) {
    t.test(value ~ Var2, combos[combos[, "Var2"] %in% x, ])$statistic
  }, simplify = TRUE)
})

rownames(out) <- RowNames
out
#         gene1      gene2      gene3       gene4      gene5
# AB -0.5407966  0.5900350 -0.2040539 0.682506188 -0.4384258
# AC -0.5035088 -0.7822292  1.7263502 0.593321770 -0.9283003
# BC  0.1573869 -1.6454483  1.4385252 0.009627409 -0.6112264