我有一个杂乱的、高度嵌套的列表:
m <- list('form' = list('elements' = list('name' = 'Bob', 'code' = 12), 'name' = 'Mary', 'code' = 15))
> m
$form
$form$elements
$form$elements$name
[1] "Bob"
$form$elements$code
[1] 12
$form$name
[1] "Mary"
$form$code
[1] 15
如何从对象 m
中提取 name
和 code
,而不管 name
的嵌套方式如何code
出现在列表中?
预期输出:
# A tibble: 2 x 2
name code
<chr> <dbl>
1 Bob 12
2 Mary 15
最佳答案
1) rrapply 展平 m
使用 rrapply
给予 r
然后将unlist(r)
的name和code字段分开使用 tapply
, 使用 c
删除尺寸, 转换为 data.frame 并设置列的顺序。
请注意,这不是硬编码为名称和代码,而是可以与其他字段和字段数一起使用。
library(rrapply)
r <- rrapply(m, f = c, how = "flatten")
nms <- names(r)
as.data.frame(c(tapply(unname(r), nms, unlist)))[unique(nms)]
给予:
name code
1 Bob 12
2 Mary 15
上面最后两行代码的替代方法是:
out <- unstack(stack(r))
out[] <- lapply(out, type.convert)
如果m
中可以有其他字段除了name
和 code
我们想要忽略然后使用它来代替定义 r
的语句以上:
cond <- function(x, .xname) .xname %in% c("name", "code")
r <- rrapply(m, cond, c, how = "flatten")
2) Base R 下面是一个 base R 解决方案,它取消了 m
, 然后使用 tapply
如 (1) 按 names(r)
的后缀分组.与 (1) 一样,这是一种通用方法,未硬编码为 name
和 code
.请注意,工具随 R 一起提供,因此它是 Base R 的一部分。
r <- unlist(m)
nms <- tools::file.ext(names(r))
as.data.frame(c(tapply(unname(r), nms, unlist)))[unique(nms)]
关于r - 从任意深度的列表中提取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63472386/