r - 取消列出嵌套列表的倒数第二个列表

我有一个深度嵌套的列表列表。在嵌套列表的“中心”是一个包含 n 个整数的向量。我需要计算每个嵌套列表中有多少整数,然后 unlist 上面的一个级别以获得这些计数的向量(即,而不是 list(0, 1:5, 0, 0, 1:3) 在巢的中心,我想要 c(0, 5, 0, 0, 3)

这看起来相对简单 - 我能够使用 rapply 完成第一部分,即转换 list(0, 1:5, 0, 0, 1:3)list(0, 5, 0, 0, 3)我的具体问题 我需要帮助的是如何取消列出最里面的列表到一个向量(而不是 list(0, 5, 0, 0, 3) 我想要 c(0, 5, 0, 0, 3)

我搜索并尝试了各种applylapplyunlist 方法,但没有一个是完全正确的,因为它们针对的是最里面的列表.由于我要取消列出的列表是倒数第二个元素,因此我正在努力寻找一种优雅地完成此操作的方法。

在下面的示例数据中,我可以通过两种方式获得所需的结果:多个 lapply 函数或一个 for 循环。但是,我的实际数据包含更多列表和数百万个数据点,因此这些可能不是有效的选择。

以下是 (1) 示例数据,(2) 我尝试过的,以及 (3) 具有所需结构的示例数据。

示例数据

have_list <- list(scenario1 = list(method1 = list(place1 = list(0, 1:5, 0, 0, 1:3),
                                                  place2 = list(1:2, 0, 1:10, 0, 0),
                                                  place3 = list(0:19, 0, 0, 0, 0),
                                                  place4 = list(1:100, 0, 0, 1:4, 0)),
                                   method2 = list(place1 = list(1:5, 1:5, 0, 0, 1:3),
                                                  place2 = list(0, 0, 1:5, 0, 0),
                                                  place3 = list(0:19, 0, 1:7, 0, 0),
                                                  place4 = list(1:22, 0, 0, 1:4, 0)),
                                   method3 = list(place1 = list(0, 1:2, 1:6, 0, 1:3),
                                                  place2 = list(1:2, 0, 1:6, 1:4, 0),
                                                  place3 = list(0:19, 0, 0, 0, 1:2),
                                                  place4 = list(1:12, 0, 0, 1:12, 0))),
                  scenario2 = list(method1 = list(place1 = list(0, 1:5, 0, 0, 1:3),
                                                  place2 = list(1:2, 0, 1:10, 0, 0),
                                                  place3 = list(0:19, 0, 0, 0, 0),
                                                  place4 = list(1:100, 0, 0, 1:4, 0)),
                                   method2 = list(place1 = list(1:5, 1:5, 0, 0, 1:3),
                                                  place2 = list(0, 0, 1:5, 0, 0),
                                                  place3 = list(0:19, 0, 1:7, 0, 0),
                                                  place4 = list(1:22, 0, 0, 1:4, 0)),
                                   method3 = list(place1 = list(0, 1:2, 1:6, 0, 1:3),
                                                  place2 = list(1:2, 0, 1:6, 1:4, 0),
                                                  place3 = list(0:19, 0, 0, 0, 1:2),
                                                  place4 = list(1:12, 0, 0, 1:12, 0))))

我尝试过的

还有我访问过的问题:

  • Unlist LAST level of a list in R
  • R - unlist nested list of dates
  • Issues unlisting a nested-list
# Get number of integers in each nested list 
lengths <- rapply(have_list, function(x) unlist(length(x)), how = "list") # this works fine

#' Each count is currently still in its own list of length 1,
#' Convert each count to vector
#' In the "middle" the nested list:
    # I have list(0, 5, 0, 0, 3) 
    # I want c(0, 5, 0, 0, 3)

# Attempts to unlist the counts
# Unlist the counts
test1 <- rapply(lengths, unlist, how = "list") # doesn't work
test2 <- unlist(lengths, recursive = FALSE) # doesn't work
test3 <- lapply(lengths, function(x) lapply(x, unlist)) # doesnt work
test4 <- lapply(lengths, function(x) lapply(x, unlist, recursive = FALSE)) # doesnt work 
test5 <- rapply(have_list, function(x) unlist(length(x)), how = "list")  #doesnt work
test6 <- rapply(have_list, function(x) unlist(length(x)), how = "unlist")  #doesnt work

我想要的数据结构

# This works on test data but is impractical for real data
want_list <- lapply(lengths, function(w) lapply(w, function(x) lapply(x, unlist)))

# or

want_list <- lengths 

## for loops work but is not practical

for (i in 1:length(lengths)){
  for (j in 1:length(lengths[[i]])){
    for (k in 1:length(lengths[[i]][[j]])){
      want_list[[i]][[j]][[k]] <- unlist(lengths[[i]][[j]][[k]])
    }
  }
}

最佳答案

一个选项是使用 rrapply melt 嵌套的 list,用 lengths 替换 'value' 列> 然后使用 collapse

中的递归拆分 (rsplit)
library(rrapply)
library(collapse)
dat <- transform(rrapply(have_list, how = "melt"), value= lengths(value))
out <- rsplit(dat$value, dat[1:3]) 

-预期使用 OP 进行测试

identical(out, want_list)
[1] TRUE

https://stackoverflow.com/questions/71533482/

相关文章:

typescript - 修改后的模板字面量类型

laravel - 如何通过单击进入 vs 代码中的一个类

python - 如何将字典的键值对收集到 Python 中的一个大字典中?

amazon-web-services - 如何将事件从 EventBridge 发送到 Lambd

javascript - 使用javascript更新foreach循环中的数组对象

javascript - 现代 Javascript 中的闭包 VS 类

javascript - 找时间在一张图中写一个数字

visual-studio - Visual Studio 2022 无法添加服务引用且没有程序集引

r - 使用逗号分隔的长度不等的数字字符串对多列进行数学运算

ASP.NET Core 6 - 从 swagger explorer 中隐藏最小的 api 端点