代码之家  ›  专栏  ›  技术社区  ›  jay.sf

如何以干净的方式在深层嵌套列表上应用函数?

  •  1
  • jay.sf  · 技术社区  · 5 年前

    在像这样的嵌套列表中

    l <- list(list(list(111, 112, 113), list(121, 122, 123)),
              list(list(211, 212, 213), list(221, 222, 223)))
    
    > str(l )
    List of 2
     $ :List of 2
      ..$ :List of 3
      .. ..$ : num 111
      .. ..$ : num 112
      .. ..$ : num 113
      ..$ :List of 3
      .. ..$ : num 121
      .. ..$ : num 122
      .. ..$ : num 123
     $ :List of 2
      ..$ :List of 3
      .. ..$ : num 211
      .. ..$ : num 212
      .. ..$ : num 213
      ..$ :List of 3
      .. ..$ : num 221
      .. ..$ : num 222
      .. ..$ : num 223
    

    我们可以应用一个函数,例如。 length() 在第一个层面上

    lapply(l, length)
    

    但是,当在更深的嵌套级别上应用函数时,我的代码的大小会呈指数级增长。。。

    # apply length() on second level
    lapply(l, function(x)
      lapply(x, function(y) length(y)))
    
    # square every list element of second level
    lapply(l, function(x) 
      lapply(x, function(y) 
        lapply(y, function(z) z^2)))
    

    或者,要更改在较低级别列表中某些位置出现的元素(即LHS的修改),我没有比执行for循环更好的主意。

    # subtract 1 from first element of each second level list
    for(i in sequence(length(l))) {
      l[[i]][[1]][[1]] <- l[[i]][[1]][[1]] - 1
      l[[i]][[2]][[1]] <- l[[i]][[2]][[1]] - 1
    }
    

    基尔 解决?

    1 回复  |  直到 5 年前
        1
  •  3
  •   s_baldur    5 年前

    根据我的经验,清单不容易掌握(希望有一天能做到)。我不知道有什么灵丹妙药,但这里有一些 小的

    lengths(l)
    # instead of
    lapply(l, length)
    
    
    lapply(l, lengths)
    # instead of
    lapply(l, function(x)
      lapply(x, function(y) length(y)))
    
    
    rapply(l, function(x) x^2, how="list") # credit to Cath
    # instead of
    lapply(l, function(x) 
      lapply(x, function(y) 
        lapply(y, function(z) z^2)))
    
    
    for (i in seq_along(l)) {
      l[[i]] <- lapply(l[[i]], function(x) {x[[1]] <- x[[1]] - 1; x})
    }
    # Instead of 
    for(i in sequence(length(l))) {
      l[[i]][[1]][[1]] <- l[[i]][[1]][[1]] - 1
      l[[i]][[2]][[1]] <- l[[i]][[2]][[1]] - 1
    }