在r中绑定特定深度的data.frames



假设我有一个更深的列表。我想提取特定深度的所有元素

下面是一个例子:

library(data.table)
library(purrr)
Data <- as.data.table(mtcars)
splitvariables <- c("am", "gear", "carb")
for(i in 1:length(splitvariables)){
Data <- map_depth(Data, .depth = i-1, .f = split, by = splitvariables[i])
}

现在Data是以下(它只是它的一部分):

$`1`
$`1`$`4`
$`1`$`4`$`4`
mpg cyl disp  hp drat    wt  qsec vs am gear carb
1:  21   6  160 110  3.9 2.620 16.46  0  1    4    4
2:  21   6  160 110  3.9 2.875 17.02  0  1    4    4
$`1`$`4`$`1`
mpg cyl  disp hp drat    wt  qsec vs am gear carb
1: 22.8   4 108.0 93 3.85 2.320 18.61  1  1    4    1
2: 32.4   4  78.7 66 4.08 2.200 19.47  1  1    4    1
3: 33.9   4  71.1 65 4.22 1.835 19.90  1  1    4    1
4: 27.3   4  79.0 66 4.08 1.935 18.90  1  1    4    1
$`1`$`4`$`2`
mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1: 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
2: 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

现在我有嵌套列表,我想要的就是绑定这些data.tables,就像如果这些data.tables没有那么深的深度,我会对rbindlist做的那样。我认为必须有一个解决方案,只有一行代码?

您可以这样做:-

a <- rbindlist(unlist(unlist(Data, recursive = FALSE), recursive = FALSE))

并且a将只是一个data.table

解决这个问题有两种不同的方法:

方案1:基于<<-赋值运算符

假设data.frame位于示例中的深度3。假设这个深度是固定的,您可以将purrr包中的map_depth与一个匿名函数组合在一起(参见下面的fun1内部)。每次调用匿名函数时,data.frame传递给它的对象被赋值给父环境中的列表对象l(因此使用<<-)。变量i允许增加列表。

library(data.table)
library(purrr)
fun1 <- function() {
i <- 1L
l <- list()
map_depth(Data, 3, function(d) {l[[i]] <<- d; i <<- i + 1L})
rbindlist(l)
}
fun1()
#      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#  1: 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#  2: 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#  3: 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#  4: 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
#  5: 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
#  6: 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
#  7: 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
#  ...

方案二:基于递归函数

即使在包含data.frames的嵌套列表中不同分支的深度不固定,该解决方案也有效;但它要求所有最里面的列表都是data.frame(记住data.frame是一个列表对象)。另外,请注意,这个约束可以很容易地放松。在下面的代码中,while循环中的值3不是data.frames嵌套列表的深度,而是传递给它的典型data.frames列表的深度rbindlist函数(例如:vec_depth(list(mtcars, mtcars))= 3).

fun2 <- function(x) {
while(vec_depth(x) > 3) {x <- unlist(x, FALSE, FALSE); fun2(x)}
return(x)
}
rbindlist(fun2(Data))
#      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#  1: 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#  2: 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#  3: 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#  4: 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
#  5: 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
#  6: 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
#  7: 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
#  ...

相关内容

  • 没有找到相关文章

最新更新