-1

私はこのような行列を持っています:同じ名前を持つ列をグループ化し、関数を行列の行に適用したいと考えています。

>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

基本的には、グループ 1グループ 2A … のように同じ名前の列を入れたいと思います。その後、すべてのグループの各遺伝子の T 検定を計算します。どうすればこれを行うことができますか?最初に: グループ化してから、異なるグループ間の各遺伝子の T スコアを返す T 検定を適用します。B

4

1 に答える 1

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(行ごとに 1 つの遺伝子を想定しています)。また、結果のベクトルに を追加し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。ベクトルの各値は 1 つの行を表し、各ベクトル全体は 1 つの列値の組み合わせ (AB、AC、または BC) を表すことがわかっているためdimnames、結果の にそれを使用できます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

いくつかの手動検証:

## 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 

アップデート

@EDiの答えに基づいて、別のアプローチがあります。meltfrom "reshape2" を使用して、データを "long" 形式に変換します。そこから、以前と同様に、必要なものを取得するための非常に簡単なサブセット化作業です。そこの出力は、純粋な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

最初のオプションは、少なくともこの小さなデータセットではかなり高速です。

microbenchmark(fun1(), fun2())
# Unit: milliseconds
#    expr       min        lq    median       uq      max neval
#  fun1()  8.812391  9.012188  9.116896  9.20795 17.55585   100
#  fun2() 42.754296 43.388652 44.263760 45.47216 67.10531   100
于 2013-10-02T09:44:36.707 に答える