我有一个这样的嵌套列表:
x <- list(x = list(a = 1,
b = 2),
y = list(a = 3,
b = 4))
Run Code Online (Sandbox Code Playgroud)
我想将嵌套列表转换为data.frames,然后将所有数据帧绑定到一个.
对于这种嵌套级别,我可以用这一行来做:
do.call(rbind.data.frame, lapply(x, as.data.frame, stringsAsFactors = FALSE))
Run Code Online (Sandbox Code Playgroud)
结果是:
a b
x 1 2
y 3 4
Run Code Online (Sandbox Code Playgroud)
我的问题是,无论嵌套程度如何,我都希望实现这一目标.此列表的另一个示例:
x <- list(X = list(x = list(a = 1,
b = 2),
y = list(a = 3,
b = 4)),
Y = list(x = list(a = 1,
b = 2),
y = list(a = 3,
b = 4)))
do.call(rbind.data.frame, lapply(x, function(x) do.call(rbind.data.frame, lapply(x, as.data.frame, stringsAsFactors = FALSE))))
a b
X.x 1 2
X.y 3 4
Y.x 1 2
Y.y 3 4
Run Code Online (Sandbox Code Playgroud)
有没有人有想法将其归结为任何嵌套级别?谢谢你的帮助
从Spacedman借贷和flodel 在这里,我们可以定义以下对递归函数:
library(tidyverse) # I use dplyr and purrr here, plus tidyr further down below
depth <- function(this) ifelse(is.list(this), 1L + max(sapply(this, depth)), 0L)
bind_at_any_depth <- function(l) {
if (depth(l) == 2) {
return(bind_rows(l))
} else {
l <- at_depth(l, depth(l) - 2, bind_rows)
bind_at_any_depth(l)
}
}
Run Code Online (Sandbox Code Playgroud)
我们现在可以将任意深度列表绑定到单个data.frame中:
bind_at_any_depth(x)
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)# A tibble: 2 × 2 a b <dbl> <dbl> 1 1 2 2 3 4
bind_at_any_depth(x_ext) # From P Lapointe
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)# A tibble: 5 × 2 a b <dbl> <dbl> 1 1 2 2 5 6 3 7 8 4 1 2 5 3 4
如果要跟踪每行的来源,可以使用此版本:
bind_at_any_depth2 <- function(l) {
if (depth(l) == 2) {
l <- bind_rows(l, .id = 'source')
l <- unite(l, 'source', contains('source'))
return(l)
} else {
l <- at_depth(l, depth(l) - 2, bind_rows, .id = paste0('source', depth(l)))
bind_at_any_depth(l)
}
}
Run Code Online (Sandbox Code Playgroud)
这将添加一source列:
bind_at_any_depth2(x_ext)
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)# A tibble: 5 × 3 source a b * <chr> <dbl> <dbl> 1 X_x_1 1 2 2 X_y_z 5 6 3 X_y_zz 7 8 4 Y_x_1 1 2 5 Y_y_1 3 4
注意:在某些时候你可以使用purrr::depth,并且需要更改at_depth为modify_depth他们的新版本推出到CRAN时(感谢@ManuelS).
| 归档时间: |
|
| 查看次数: |
1233 次 |
| 最近记录: |