1

我有 3 个数据集,我排列了 10 倍。数据集的每个排列在 3 个矩阵中构成一列(每个数据集一个矩阵)。这 3 个矩阵 ( m1, m2, m3) 在一个列表中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=1m.res将产生:

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

我显然需要lapply/的教程,sapply因为这不应该这么难。

4

2 回答 2

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 回答
2

首先,我们应该获得检索一行的正确方法。所以,对于第 1 行 (1,1,1)

我们想遍历 的三个元素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功能plyr,它的工作原理完全一样apply,但总是返回一个列表(请参阅Force apply to return a list

但是,在这种情况下,我们需要取消列出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 回答