如何基于另一个列表对列表中的矩阵进行子集化,其值指示列号

时间:2018-11-21 13:15:35

标签: r subset lapply

我有一个矩阵列表(mat_list)。我想用每个矩阵中选定的列子集创建一个新列表。我还有另一个数字列表(col_list),该列表指示要保留的列号。 示例数据集:

> mat_list <- list(structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L), .Dim = c(4L, 3L), .Dimnames = list(NULL, c("V1", "V2", "V3"))),structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L), .Dim = c(4L, 3L), .Dimnames = list(NULL, c("V1", "V2", "V3")))) ; names(mat_list) <- c("mat1","mat2")
> mat_list
$mat1
     V1 V2 V3
[1,]  1  5  9
[2,]  2  6 10
[3,]  3  7 11
[4,]  4  8 12

$mat2
     V1 V2 V3
[1,]  1  5  9
[2,]  2  6 10
[3,]  3  7 11
[4,]  4  8 12

> col_list <- list(structure(c(1,3)),structure(c(2,3))) ; names(col_list) <- c("var1","var2")
> col_list
$var1
[1] 1 3

$var2
[1] 2 3

我想要以下输出:

> my_list
$mat1
     V1 V3
[1,]  1  9
[2,]  2  10
[3,]  3  11
[4,]  4  12

$mat2
     V2 V3
[1,]  5  9
[2,]  6 10
[3,]  7 11
[4,]  8 12

我尝试使用lapply在所有矩阵中对这些列进行子集化。我最接近的是做

> lapply(mat_list,function(x) x[,col_list$var1])
$mat1
     V1 V3
[1,]  1  9
[2,]  2 10
[3,]  3 11
[4,]  4 12

$mat2
     V1 V3
[1,]  1  9
[2,]  2 10
[3,]  3 11
[4,]  4 12

这使用col_var1中的值应用于mat_list中的所有矩阵。但是我无法成功将其应用于col_list的所有(两个)元素-例如通过将

应用于var_list
lapply(mat_list,function(x) x[,lapply(var_list)])

我感谢您的投入。

1 个答案:

答案 0 :(得分:2)

在这种情况下,lapplymapply更合适:

mapply(function(x, y) x[, y], mat_list, col_list, SIMPLIFY = FALSE)

也等同于

Map(function(x, y) x[, y], mat_list, col_list)

这两种方法都通过同时从mat_listcol_list中获取相应的参数来应用指定的功能。

lapply不起作用的原因是,正如您所注意到的,它仅遍历单个变量。要使用lapply,则需要

lapply(seq_along(mat_list), function(i) mat_list[[i]][, col_list[[i]]])

奖金:如果mat_list包含数据帧而不是矩阵,则可能更简洁

mapply(`[`, mat_list, col_list, SIMPLIFY = FALSE)
# or
Map(`[`, mat_list, col_list)