我有这个单层列表:

have <- list("a" = 1, "b.a" = 2, "b.b" = 3)

我需要这两层列表:

need <- list("a" = 1, "b" = list("a" = 2, "b" = 3))

如果解决方案可以是递归的就更好了.我们的目标是将数据 struct 化,因为它可以被解析为一些JSON文件.

谢谢!

推荐答案

这个递归函数应该可以做到这一点:

f <- function(obj) {
  nms <- lapply(strsplit(names(obj), '\\.'), function(x){
    if(length(x) == 1) x else c(x[1], paste(x[-1], collapse = '.'))
  })
  first_nms <- sapply(nms, `[`, 1)
  last_nms <- sapply(nms, `[`, -1)
  un_nms <- unique(first_nms)
  setNames(lapply(un_nms, function(x) {
    o <- unname(obj[first_nms %in% x])
    if(length(o) == 1) unlist(o) else
      f(setNames(o, last_nms[first_nms %in% x]))
    }), un_nms)
}

测试,我们有:

have <- list("a" = 1, "b.a" = 2, "b.b" = 3)

f(have)
#> $a
#> [1] 1
#> 
#> $b
#> $b$a
#> [1] 2
#> 
#> $b$b
#> [1] 3

我们可以看到它在深度嵌套的列表上工作:

f(list(a = 1, b.a = 2, b.b = 3, c.a.a = 4, c.a.b = 5, c.b.a = 6, c.b.b = 7))
#> $a
#> [1] 1
#> 
#> $b
#> $b$a
#> [1] 2
#> 
#> $b$b
#> [1] 3
#> 
#> 
#> $c
#> $c$a
#> $c$a$a
#> [1] 4
#> 
#> $c$a$b
#> [1] 5
#> 
#> 
#> $c$b
#> $c$b$a
#> [1] 6
#> 
#> $c$b$b
#> [1] 7

R相关问答推荐

按R中不同长度的组将日期时间列值四舍五入到小时

如何通过Exams2黑板对非整数字的问题进行评分

使用gsim删除特殊词

使用Shiny组合和显示复制和粘贴的数据

编码变量a、b、c以匹配来自另一个数据点的变量x

从有序数据中随机抽样

获取列中值更改的行号

如何通过Docker部署我的shiny 应用程序(多个文件)

迭代通过1个长度的字符串长字符R

如何自定义3D散点图的图例顺序?

一小时满足条件的日期的 Select

计算数据帧中指定值之前的行数,仅基于每行之后的future 行,单位为r

派生程序包| ;无法检索';return()';的正文

将全局环境变量的名称分配给列表中的所有元素

仅当后续值与特定值匹配时,才在列中回填Nas

判断函数未加载R中的库

快速合并R内的值

当由base::限定时,`[.factor`引发NextMethod错误

R:如何在数据集中使用Apply

使用同一行中的前一个值填充R矩阵中的缺失值