【问题标题】:using rbindlists for nested lists in R将 rbindlists 用于 R 中的嵌套列表
【发布时间】:2020-08-06 11:33:43
【问题描述】:

我有一个嵌套列表,如下所示。这是一个简化的例子,我的原始数据有数百个项目。

mtcars
mtcars <- mtcars[1:15,]
mtcars <- as.data.table(mtcars)

iris
iris <- iris[1:10,]
iris <- as.data.table(iris)

result <- vector("list", 3)
names <- c("Item 1", "Item 2", "Item 3")
names(result) <- names

testList1 <- list(mtcars, iris)

rm(result)
result <- list(Item1 = list(cars = mtcars,
                            flowers = iris),
               Item2 = list(cars = mtcars,
                            flowers = iris),
               Item3 = list(cars = mtcars,
                            flowers = iris))

我想总结一下结果,这样我就变成了两个数据表:一个用于flowers,另一个用于cars。

我尝试使用result &lt;- rbindlist(result, use.names = TRUE, fill = TRUE),但这会导致错误。

期望的结果是:

testList1 <- list(iris, iris, iris)
flowers <- rbindlist(testList1, use.names = TRUE, fill = TRUE)
flowers

testList1 <- list(mtcars, mtcars, mtcars)
cars <- rbindlist(testList1, use.names = TRUE, fill = TRUE)
cars

考虑到原始results比示例大得多,我该如何绑定嵌套列表?

【问题讨论】:

    标签: r list data.table rbind


    【解决方案1】:

    您可以使用purrr 的transpose 和来自dplyr 的bind_rows。

    library(purrr)
    transpose(result) %>% map(dplyr::bind_rows)
    
    #$cars
    #     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: 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
    # 5: 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
    #...
    
    #$flowers
    #    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    # 1:          5.1         3.5          1.4         0.2  setosa
    # 2:          4.9         3.0          1.4         0.2  setosa
    # 3:          4.7         3.2          1.3         0.2  setosa
    # 4:          4.6         3.1          1.5         0.2  setosa
    # 5:          5.0         3.6          1.4         0.2  setosa
    #...
    

    我们可以添加一个'id' 列:

    transpose(result) %>% map(dplyr::bind_rows, .id = "id")
    
    #$cars
    #     mpg cyl  disp  hp drat    wt  qsec vs am gear carb    id
    # 1: 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4 Item1
    # 2: 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4 Item1
    # 3: 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1 Item1
    #...
    #...
    #43: 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3 Item3
    #44: 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3 Item3
    #45: 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4 Item3
    #     mpg cyl  disp  hp drat    wt  qsec vs am gear carb    id
    
    #$flowers
    #    Sepal.Length Sepal.Width Petal.Length Petal.Width Species    id
    # 1:          5.1         3.5          1.4         0.2  setosa Item1
    # 2:          4.9         3.0          1.4         0.2  setosa Item1
    # 3:          4.7         3.2          1.3         0.2  setosa Item1
    #...
    #29:          4.4         2.9          1.4         0.2  setosa Item3
    #30:          4.9         3.1          1.5         0.1  setosa Item3
    #    Sepal.Length Sepal.Width Petal.Length Petal.Width Species    id
    

    【讨论】:

    • 是否可以为每一行添加一个指示符?第 1 项、第 2 项还是第 3 项?
    • 转置功能在我的真实数据上失败。我刚刚在我的读取数据中注意到,我的一个项目,比如 Item2 没有花桌,相信这是失败的原因。我该如何克服呢?
    • 您可以将bind_rows 与.id 一起使用。查看更新的答案。
    【解决方案2】:

    如果我们遍历内部列表的names,我们可以使用rbindlist

    library(data.table)
    lapply(setNames(names(result[[1]]), names(result[[1]])), 
            function(nm)  rbindlist(lapply(result, `[[`, nm)))
    #$cars
    #     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: 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
    # 5: 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
    # 6: 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
    # 7: 14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
    # 8: 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
    # 9: 22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
    # ...
    
    
    #$flowers
    #    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    # 1:          5.1         3.5          1.4         0.2  setosa
    # 2:          4.9         3.0          1.4         0.2  setosa
    # 3:          4.7         3.2          1.3         0.2  setosa
    # 4:          4.6         3.1          1.5         0.2  setosa
    # 5:          5.0         3.6          1.4         0.2  setosa
    # 6:          5.4         3.9          1.7         0.4  setosa
    # 7:          4.6         3.4          1.4         0.3  setosa
    # 8:          5.0         3.4          1.5         0.2  setosa
    # ..
    

    如果我们需要'id',则在rbindlist 中指定idcol 选项

    lapply(setNames(names(result[[1]]), names(result[[1]])),
        function(nm)  rbindlist(lapply(result, `[[`, nm), idcol = 'id'))
    

    【讨论】:

      猜你喜欢
      • 2021-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-03
      • 2012-05-24
      • 1970-01-01
      • 2021-11-25
      相关资源
      最近更新 更多