根据多个变量拆分创建嵌套列表

Create nested list based on split by multiple variables

为了将一个函数应用到一个较大数据集中的多个较小数据集,我需要通过多个变量对大型数据集进行拆分。但是,为了进一步使用子数据集,我想将它们存储在一个嵌套列表中,并将不同的分组变量作为列表节点名称(与 rapply 一起使用)。

一个例子:

head_mtcars <- head(mtcars, 10)

我从here知道我可以使用list(data$V1, data$V2)拆分数据集,但不幸的是生成的列表只将分组变量保持在同一级别。我希望列表节点像 </code>、<code> 等:

split(head_mtcars, list(head_mtcars$cyl, head_mtcars$gear), drop = T)

$`6.3`
                mpg cyl disp  hp drat    wt  qsec vs am gear carb
Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
Valiant        18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

$`8.3`
                   mpg cyl disp  hp drat   wt  qsec vs am gear carb
Hornet Sportabout 18.7   8  360 175 3.15 3.44 17.02  0  0    3    2
Duster 360        14.3   8  360 245 3.21 3.57 15.84  0  0    3    4

$`4.4`
            mpg cyl  disp hp drat   wt  qsec vs am gear carb
Datsun 710 22.8   4 108.0 93 3.85 2.32 18.61  1  1    4    1
Merc 240D  24.4   4 146.7 62 3.69 3.19 20.00  1  0    4    2
Merc 230   22.8   4 140.8 95 3.92 3.15 22.90  1  0    4    2

$`6.4`
               mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Mazda RX4     21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Merc 280      19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4

我也尝试更改分隔符,但这没有帮助:

## only changes the naming separator to a $ but does not actually create a new list level:
split(head_mtcars, list(head_mtcars$cyl, head_mtcars$gear), drop = T, sep = "$")

$`6`
                mpg cyl disp  hp drat    wt  qsec vs am gear carb
Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
Valiant        18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

$`8`
                   mpg cyl disp  hp drat   wt  qsec vs am gear carb
Hornet Sportabout 18.7   8  360 175 3.15 3.44 17.02  0  0    3    2
Duster 360        14.3   8  360 245 3.21 3.57 15.84  0  0    3    4

$`4`
            mpg cyl  disp hp drat   wt  qsec vs am gear carb
Datsun 710 22.8   4 108.0 93 3.85 2.32 18.61  1  1    4    1
Merc 240D  24.4   4 146.7 62 3.69 3.19 20.00  1  0    4    2
Merc 230   22.8   4 140.8 95 3.92 3.15 22.90  1  0    4    2

$`6`
               mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Mazda RX4     21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Merc 280      19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4

我还尝试修改 中的代码以与多个拆分变量一起使用,但这会将组变量移动到 dimnames,我不知道如何(如果可能的话)完全)转换为嵌套列表级别(仅使用一个分组变量时效果很好)。

by(head_mtcars, list(head_mtcars$cyl, head_mtcars$gear), identity, simplify = FALSE)

: 4
: 3
NULL
------------------------------------------------------------- 
: 6
: 3
                mpg cyl disp  hp drat    wt  qsec vs am gear carb
Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
Valiant        18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
------------------------------------------------------------- 
: 8
: 3
                   mpg cyl disp  hp drat   wt  qsec vs am gear carb
Hornet Sportabout 18.7   8  360 175 3.15 3.44 17.02  0  0    3    2
Duster 360        14.3   8  360 245 3.21 3.57 15.84  0  0    3    4
------------------------------------------------------------- 
: 4
: 4
            mpg cyl  disp hp drat   wt  qsec vs am gear carb
Datsun 710 22.8   4 108.0 93 3.85 2.32 18.61  1  1    4    1
Merc 240D  24.4   4 146.7 62 3.69 3.19 20.00  1  0    4    2
Merc 230   22.8   4 140.8 95 3.92 3.15 22.90  1  0    4    2
------------------------------------------------------------- 
: 6
: 4
               mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Mazda RX4     21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Merc 280      19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
------------------------------------------------------------- 
: 8
: 4
NULL

我也尝试了各种 tidyverse 方法,但其中 none 确实解决了问题。

最后,我想要一个嵌套列表,其中 $cyl 的级别作为第一级别,$gear 的级别作为下面的级别。有什么建议吗?

这是使用 reduce()map_depth().

嵌套拆分任意次数的方法

请注意,split() 的公式界面是一项相对较新的功能,因此如果它不起作用,您可能需要升级到更新的版本。

library(purrr)

head_mtcars <- head(mtcars, 10)

fms <- list(~cyl, ~gear, ~carb)

reduce(.x = fms, .f = ~ map_depth(.x, .depth = vec_depth(.x) - 2,  split, .y), .init = head_mtcars)

$`4`
$`4`$`4`
$`4`$`4`$`1`
            mpg cyl disp hp drat   wt  qsec vs am gear carb
Datsun 710 22.8   4  108 93 3.85 2.32 18.61  1  1    4    1

$`4`$`4`$`2`
           mpg cyl  disp hp drat   wt qsec vs am gear carb
Merc 240D 24.4   4 146.7 62 3.69 3.19 20.0  1  0    4    2
Merc 230  22.8   4 140.8 95 3.92 3.15 22.9  1  0    4    2

$`6`
$`6`$`3`
$`6`$`3`$`1`
                mpg cyl disp  hp drat    wt  qsec vs am gear carb
Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
Valiant        18.1   6  225 105 2.76 3.460 20.22  1  0    3    1


$`6`$`4`
$`6`$`4`$`4`
               mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Mazda RX4     21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Merc 280      19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4

$`8`
$`8`$`3`
$`8`$`3`$`2`
                   mpg cyl disp  hp drat   wt  qsec vs am gear carb
Hornet Sportabout 18.7   8  360 175 3.15 3.44 17.02  0  0    3    2

$`8`$`3`$`4`
            mpg cyl disp  hp drat   wt  qsec vs am gear carb
Duster 360 14.3   8  360 245 3.21 3.57 15.84  0  0    3    4