r - 将列表列的*特定*元素提取到新列

标签 r tidyverse purrr

在 R 中,我知道如何将(命名)列表列的元素提取到单独的列中,前提是它们的长度相同:

library(tidyverse)

tib1 <- tibble(x = 1:3, y = list(list(a = 1, b = 2, c = 3),
                                 list(a = 3, b = 4, c = 5),
                                 list(a = 5, b = 6, c = 7)))
tib1
# A tibble: 3 x 2
      x y         
  <int> <list>    
1     1 <list [3]>
2     2 <list [3]>
3     3 <list [3]>
bind_cols(tib1[1], bind_rows(tib1$y))
    # A tibble: 3 x 4
      x     a     b     c
  <int> <dbl> <dbl> <dbl>
1     1  1.00  2.00  3.00
2     2  3.00  4.00  5.00
3     3  5.00  6.00  7.00

问题是一旦列表中的一个元素的长度不同(这里是a):

tib2 <- tibble(x = 1:3, y = list(list(a = 1:2, b = 2, c = 3),
                                 list(a = 3:4, b = 4, c = 5),
                                 list(a = 5:6, b = 6, c = 7)))

bind_cols(tib2[1], bind_rows(tib2$y))

Error in bind_rows_(x, .id) : Argument 2 must be length 2, not 1

有没有一种优雅的方式告诉 R 在提取中不包含 a,或者只包含 bc,或者只包含 bc包含长度相同的元素l?希望以“pipe-ish”、“tidyverse-ish”的方式?

预期结果应该以某种方式保留a,或者简单地保留整个y字段,以便我将来可以以某种方式访问​​它:

tibble(x = 1:3, y = list(list(a = 1:2, b = 2, c = 3),
                         list(a = 3:4, b = 4, c = 5),
                         list(a = 5:6, b = 6, c = 7)),
       b = c(2, 4, 6),
       c = c(3, 5, 7))
# A tibble: 3 x 4
      x y              b     c
  <int> <list>     <dbl> <dbl>
1     1 <list [3]>  2.00  3.00
2     2 <list [3]>  4.00  5.00
3     3 <list [3]>  6.00  7.00

或者最好作为新的列表列:

tibble(x = 1:3,
       a = list(1:2, 3:4, 5:6),
       b = c(2, 4, 6),
       c = c(3, 5, 7))
# A tibble: 3 x 4
      x a             b     c
  <int> <list>    <dbl> <dbl>
1     1 <int [2]>  2.00  3.00
2     2 <int [2]>  4.00  5.00
3     3 <int [2]>  6.00  7.00

最佳答案

这也是一个基本的 R 解决方案,

dd <- data.frame(x = tib2$x, t(do.call(cbind, tib2$y)))

这给出了,

  x    a b c
1 1 1, 2 2 3
2 2 3, 4 4 5
3 3 5, 6 6 7

检查结构,我们看到所有三列都是列表。

 str(dd)
'data.frame':   3 obs. of  4 variables:
 $ x: int  1 2 3
 $ a:List of 3
  ..$ : int  1 2
  ..$ : int  3 4
  ..$ : int  5 6
 $ b:List of 3
  ..$ : num 2
  ..$ : num 4
  ..$ : num 6
 $ c:List of 3
  ..$ : num 3
  ..$ : num 5
  ..$ : num 7

如果您想取消列出 bc,那么只需:

dd[-c(1, 2)] <- lapply(dd[-c(1, 2)], unlist)

给出了结构:

str(dd)
'data.frame':   3 obs. of  4 variables:
 $ x: int  1 2 3
 $ a:List of 3
  ..$ : int  1 2
  ..$ : int  3 4
  ..$ : int  5 6
 $ b: num  2 4 6
 $ c: num  3 5 7

关于r - 将列表列的*特定*元素提取到新列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49094974/

相关文章:

r - 对颜色/流程进行分组,以便条形图创建第一个条形图

r - 在 R 中合并 data.frame

r - 根据文件在 R 中保存的日期提取文件名

r - 计算数据,按年份和按区域划分的R

r - 除以 Tidyverse 中 mutate 的最后一行

r - 如何根据 tidy data.frame 提供的值在 ggplot 中的标题中添加文本

r - 使用 purrr 处理顺序任务

R粘贴字符串折叠 - 如何用引号保留字符串?

r - 使用 purrr 帮助转换大型数据文件

r - 在 vector/data.frame 列上应用返回 data.frame/tibble 的函数并绑定(bind)结果