1

10 倍に並べ替えた 3 つのデータセットがあります。データセットの各順列は、3 つの行列 (データセットごとに 1 つの行列) の列を作成します。これら 3 つの行列 ( m1m2m3) はリストにありますL。各エントリ (この場合は 4) について可能なすべての組み合わせ (10x10x10=1000) を調べたいと思います。expand.grid を使用して、別の行列の行にある 3 つの行列全体で列呼び出しのすべての組み合わせを提供しましたM

M<-expand.grid(seq(1:10),seq(1:10),seq(1:10))

リスト内の私のデータは次のとおりです。

m1<-matrix(c(1,2,1,0,3,2,1,2,3,4),nrow=4, ncol=10)
m2<-matrix(c(m1[1,]),nrow=4,ncol=10)
m3<-matrix(c(m1[2,]),nrow=4,ncol=10)
L<-list(m1, m2, m3)

do.call, cbind, lapply/sapplyを使用して、M から列座標を効率的に取得し、L に含まれる 3 つの行列の対応する列を調べて、それらを新しい行列にバインドするのを手伝ってもらえますか。

m.res<-for (i in 1:nrow(M) { "get" L[[1:3]][M[i,]] }

の場合i=1、次のm.res結果が得られます。

1 1 2
2 3 2
1 3 4
0 1 0

これはそれほど難しくないはずなので、 lapply/のチュートリアルが明らかに必要です。sapply

4

2 に答える 2

2

まず、1 行を取得する正しい方法を取得する必要があります。したがって、1行目 (1,1,1)

の 3 つの要素をループして、L行 1 のインデックスを持つ行列を取得します。M

col.ids <- unlist(M[1,])
# sapply will already return the columns in a matrix
# We use seq_along rather than looping directly on L, because we also need the
# id for col.ids
sapply(seq_along(L), function(id){
                        L[[id]][ ,col.ids[id] ]
                        })

     [,1] [,2] [,3]
[1,]    1    1    2
[2,]    2    3    2
[3,]    1    3    4
[4,]    0    1    0

applyそれを別のステートメントに入れるだけで、設定は完了です。

今回は apply を使用し、 の行を直接ループします(したがって、変数Mは必要ありません)。col.ids

# The second parameter is 1 for rows and 2 for columns
m.comb <- apply(M, 1, function(cols)
                      {
                      sapply(seq_along(L), function(id){
                                               L[[id]][ ,cols[id] ]
                                               })
                      })

さて、apply大きな 12 x 1000 の行列が得られますが、この場合は非常に煩わしいので、これをリストに変更する必要があります...これは、読者への演習として残しておきます...

...またはむしろ、パッケージのalply関数を使用します。これは、まったく同じように機能しますが、常にリストを返します ( Force apply to return a list を参照)plyrapply

ただし、この場合は非公開にする必要がありますcols

library(plyr)
m.comb.2 <- alply(M, 1, function(cols)
                       {
                       cols <- unlist(cols)
                       sapply(seq_along(L), function(id)
                              {
                              L[[id]][ ,cols[id] ]
                              })
                       })

そして最後に...

m.comb.2[[1]]

     [,1] [,2] [,3]
[1,]    1    1    2
[2,]    2    3    2
[3,]    1    3    4
[4,]    0    1    0

m.comb.2[[10]]

     [,1] [,2] [,3]
[1,]    1    1    2
[2,]    2    3    2
[3,]    3    3    4
[4,]    4    1    0
于 2013-11-02T08:32:51.027 に答える
2

[@nico の回答にコメントとして追加しますが、コメントよりもクリーンで拡張したかったのです。@nico が詳細な回答に追加することが有用であると判断した場合、私の回答は削除する必要があります。]

を使用することもmapplyできます。つまり、取得関数を複数の引数に適用できます (引数が 3 つしかないため) M

#`M` is your dataframe of arguments and `L` is your list of matrices
#save all results to a list (`myls`)
myls <- mapply(function(colmat1, colmat2, colmat3) 
               { cbind(L[[1]][,colmat1], L[[2]][,colmat2], L[[3]][,colmat3]) }, 
                      M[,1], M[,2], M[,3], SIMPLIFY = F)

myls[[1]]
#     [,1] [,2] [,3]
#[1,]    1    1    2
#[2,]    2    3    2
#[3,]    1    3    4
#[4,]    0    1    0
myls[[10]]
#     [,1] [,2] [,3]
#[1,]    1    1    2
#[2,]    2    3    2
#[3,]    3    3    4
#[4,]    4    1    0
于 2013-11-02T11:56:58.057 に答える