“更好的方法”;“合并”;R中多个列表中的多元素索引的所有组合?

“更好的方法”;“合并”;R中多个列表中的多元素索引的所有组合?,r,list,for-loop,apply,mapply,R,List,For Loop,Apply,Mapply,假设我有两个列表,每个列表包含多个索引中多个子元素的可变编号: list.a <- list(c("a","b","c"), c("x", "y", "z")) list.b <- list(c("d", "e", "f","g"), c("m", "n")) 及 如何从每个列表的相应索引递归访问子元素的每个组合 例如,我想访问a-d、a-e、a-f、a-g、b-d、b-e。。。依此类推,第一个索引和每个列表的第二个索引的x-m、x-n、y-m、y-n、z-m和z-n [[1

假设我有两个列表,每个列表包含多个索引中多个子元素的可变编号:

list.a <- list(c("a","b","c"), c("x", "y", "z"))
list.b <- list(c("d", "e", "f","g"), c("m", "n"))

如何从每个列表的相应索引递归访问子元素的每个组合

  • 例如,我想访问a-d、a-e、a-f、a-g、b-d、b-e。。。依此类推,第一个索引和每个列表的第二个索引的x-m、x-n、y-m、y-n、z-m和z-n

    [[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
当我从每个列表中有多个子元素时(特别是当两个列表中的元素数量不相等时),似乎不起作用:

  • 它跳过了一半的组合,而只是循环使用两个列表中较短的一个。我希望它能够将两个列表中共享索引中的所有组合组合组合起来
我知道我也可以使用
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)
    }
}
…但是循环充其量是混乱的,并且随着大量列表的出现变得相当缓慢

有更好的方法吗?

  • 具体来说,是否有一种特殊的函数或某种方法来使用
    apply
    函数,从而更有效地完成此任务


(本部分不需要回答问题,但提供了其使用的上下文/扩展):

对于那些好奇的人,我想把它扩展到
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
    

    l1您需要
    展开.grid
    ,它用于:

    从提供的矢量或矢量的所有组合创建数据帧 因素

    使用
    do.call(粘贴,…)
    是将数据帧的所有列粘贴在一起

    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按年份汇总面积:


    我从来都不知道如何引用列表的不同部分。我希望我的问题有意义…谢谢@Psidom!我如何将此扩展到仅粘贴
    之外?例如,如何将此方法应用于对data.frame进行子集设置?(见我问题的后半部分)您希望按年份或地块进行合计吗?可能
    Map(函数(年,图)和(子集(dat,图%在%图中,图%在%年中)$面积),l1,l2)
    ?我想按年进行聚合。但同样,只有当绘图列在另一个列表的重合索引中时,这才是唯一的。如果按年份聚合,请尝试映射(函数(年份,绘图)和(子集(dat,绘图%in%plots&年份%in%plots),行和(面积,年份)),l1,l2)您的代码工作得很好!谢谢,伙计!如果您将注释中的代码合并到您的答案中(不是覆盖当前的答案,而是添加到解释每种方法的代码中),我很乐意接受这一点:D。
    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"
    
    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
    
    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
    
    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"
    
    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