假设我有两个列表,每个列表包含多个索引中多个子元素的可变数量:
list.a <- list(c("a","b","c"), c("x", "y", "z"))
list.b <- list(c("d", "e", "f","g"), c("m", "n"))
这导致:
> list.a
[[1]]
[1] "a" "b" "c"
[[2]]
[1] "x" "y" "z"
和
> list.b
[[1]]
[1] "d" "e" "f" "g" "h"
[[2]]
[1] "m" "n"
如何递归访问每个列表中相应索引的每个组合子元素?
例如,我想访问第一个索引和xm,xn,ym,yn,zm和zn的ad,ae,af,ag,bd,be,...等组合从每个列表的第二个索引。
[[1]]
[1] "a d" "a e" "a f" "a g" "b d" "b e" "b f" "b g" "c d" "c e" "c f" "c g"
[[2]]
[1] "x m" "x n" "y m" "y n" "z m" "z n"
mapply
似乎不起作用(特别是如果两个列表中的元素数量不相等):
> mapply(paste,list.a,list.b)
[[1]]
[1] "a d" "b e" "c f" "a g"
[[2]]
[1] "x m" "y n" "z m"
我知道我也可以使用for
循环......:
list.d <- list()
for(i in 1:length(list.a)) {
list.c <- list()
list.d[[i]] <- {
for(j in list.a[[i]]) {
for(k in list.b[[i]]) {
list.c <- c(list.c, paste(j, k))
}
}
unlist(list.c)
}
}
产生所需的结果:
> list.d
[[1]]
[1] "a d" "a e" "a f" "a g" "b d" "b e" "b f" "b g" "c d" "c e" "c f" "c g"
[[2]]
[1] "x m" "x n" "y m" "y n" "z m" "z n"
...但是这个循环充其量是凌乱的,而且对于庞大的列表来说变得相当慢。
有更好的方法吗?
apply
函数是否有特殊功能或某种方法可以更有效地完成此任务?&LT;申请&gt;
(这部分不是回答问题,而是提供其使用的背景/扩展):
对于那些好奇的人,我想将其扩展到paste()
之外,而是想在data.frame上使用它。
例如:
假设我有两个列表,每个列表包含多个具有多个子元素的索引:
l1 <- list(c(1933:1935),c(1950:1954), c(2012:2013)) #groups of years
l2 <- list(c(19:21),c(19:24),c(22:26)) #groups of plot numbers
我们还假设我有以下data.frame:
dat <- data.frame(plot = rep(1:30,81), year = rep(1933:2013, each = 30), area = sample(270))
> head(dat)
plot year area
1 1 1933 137
2 2 1933 72
3 3 1933 136
4 4 1933 187
5 5 1933 206
6 6 1933 74
我想创建一个新列表(我们称之为l3
),其中包含l1
(年)和l2
的所有组合的总和区域(图)对于每个重合列表索引。
例如,结果列表的[[1]]
的结果将是1933年,1934年<19>的每个地块的总和,20 &amp; 21 < em>&amp; 1935年。
[[2]]
的结果将是1950年至1954年每年19至24年的总面积。
答案 0 :(得分:1)
您需要expand.grid
,用于:
从提供的矢量的所有组合创建数据框 因素。
使用do.call(paste, ...)
将数据框的所有列粘贴在一起。
Map(function(a,b) do.call(paste, expand.grid(a,b)), list.a, list.b)
#[[1]]
# [1] "a d" "b d" "c d" "a e" "b e" "c e" "a f" "b f" "c f" "a g" "b g" "c g"
#[[2]]
#[1] "x m" "y m" "z m" "x n" "y n" "z n"
对于问题的第二部分,我们可以逐年对数据框进行子集化并首先绘制图,然后使用 rowsum area 汇总到年 >:
Map(function(years, plots) {
with(subset(dat, plot %in% plots & year %in% years), rowsum(area, year))
}, l1, l2)
[[1]]
[,1]
1933 257
1934 398
1935 640
[[2]]
[,1]
1950 950
1951 457
1952 601
1953 1202
1954 1148
[[3]]
[,1]
2012 736
2013 497