首页 > 解决方案 > 如何将包含不同长度字符向量的 R 列表拆分为特定列?

问题描述

我有一些 JSON 格式的数据,使用 jsonlite 我能够读入 R 中的数据框。我正在使用的数据位于列表中,其中每个列表包含不同长度的字符向量。例如:

  values
  <list>      
1   A
2   B
3   character(0)
4   C
5   c(A, C)
6   D
7   c(B, C)
8   c(D, E)

或者,完整复制:

structure(list(values1 = list("C", "E", character(0), "C", character(0), 
    "C", c("D", "A"), c("D", "A"), "D", "D", character(0), "D", 
    "A", "E", "E", "A", "A", "A", "B", "A", "A", "A", "A", "D", 
    "E", "E", "A", character(0), "E", character(0), character(0), 
    "B", character(0), "C", "C", "C", "C", "C", character(0), 
    character(0), character(0), character(0), character(0), character(0), 
    character(0), character(0), "E", c("E", "D"), c("E", "D"), 
    "B", "E", "E", "A", "A", "B", "B", "B", "B", "B", "D", "D", 
    character(0), character(0), character(0), character(0), "B", 
    c("C", "A"), character(0), "A", "B", "B", "B", "B", "B", 
    "C", "C", character(0), character(0), character(0), character(0), 
    "E", "E", character(0), character(0), "B", "E", "A", "C", 
    "B", "C", "A", "C", "C", "C", "C", "C", "A", character(0), 
    "A", character(0), "A", "D", "B", "A", "C", "A", "A", "A", 
    "C", "A", "A", "B", "D", "D", character(0), character(0), 
    character(0), character(0), character(0), character(0), "C", 
    "B", character(0), "B", character(0), "B", "E", "D", c("C", 
    "E"), c("C", "E"), "D", "D", "C", "C", character(0), "C", 
    character(0), "C", "C", "D", "E", "E", "B", "B", "C", "C", 
    "B", "B", "E", character(0), character(0), character(0), 
    character(0), "B", "B", "E", "A", character(0), "B", "A", 
    character(0), "A", "D", "D", c("D", "A"), c("D", "A"), c("D", 
    "B"), c("D", "B"), character(0), "E", character(0), "E", 
    "E", "E", "E", character(0), "D", character(0), "E", "A", 
    "A", "A", "A", "A", "D", "D", c("B", "A"), c("B", "A"), "C", 
    character(0), character(0), "B", "E", "E", "B", c("E", "B"
    ), "A", "A", "B", "B", "D", "D", "A", "A", character(0), 
    "A", "C", character(0), "C", "C", "B", "B", "A", "A", "B", 
    "B", "A", "E", "C", "C", "D", "D", "D", c("C", "E"), character(0), 
    character(0), character(0), character(0), "E", c("E", "A"
    ), "E", character(0), character(0), "A", "D", "D", c("D", 
    "A"), c("D", "A"), character(0), character(0), character(0), 
    character(0), character(0), character(0), "B", "C", "C", 
    "C", "C", "B", "B", c("C", "E"), c("C", "E"), "E", "C", "C", 
    "C", c("E", "D", "B", "A"), c("E", "D", "B", "A"), character(0), 
    "A", character(0), "A", c("C", "A"), c("C", "A"), c("C", 
    "A"), "E", "E", "A", character(0), "C", c("E", "D"), c("E", 
    "D"), character(0), character(0), character(0), character(0), 
    "A", "A", "A", "A", "D", "E", c("C", "D"), "E", character(0), 
    character(0), character(0), "D", "D", character(0), "A", 
    "B", character(0), character(0), character(0), character(0), 
    "D", "D", "D", "E", "E", "D", "D", "B", "B", "B", "E", "D", 
    "C", "D", "C", "C", "E", "E", "A", character(0), character(0), 
    "B", character(0), "B", "B", "B", "B", character(0), "A", 
    "C", "C", "C", "D", "D", "D", character(0), "D", character(0), 
    "D", "B", "A", character(0), "B", "D", "A", "A", character(0), 
    "A", "D", "D", "E", "E", "B", character(0), character(0), 
    character(0), "C", "C", "C", "B", "B", "A", "D", c("C", "B"
    ), character(0), "D", "C", "C", character(0), character(0), 
    "D", "D", "D", c("B", "A"), "E", "A", "A", character(0), 
    "E", "C", "B", character(0), character(0), character(0), 
    character(0), "E", "E", "D", "C", "C", "E", "E", "E", "E", 
    character(0), "E", "E", "A", "B", "A", "A", "D", "E", "E", 
    "B", "B", character(0), character(0), "D", "D", "C", "D", 
    "D", "E", character(0), "E", character(0), "E", c("D", "B"
    ), character(0), "B", character(0), character(0), "D", character(0), 
    "D", "D", "D", "C", character(0), "E", "E", c("E", "B"), 
    c("E", "B"), "E", "E", "D", "D", "B", c("E", "A"), c("E", 
    "A"), c("C", "D"), c("C", "D"), c("C", "B"), c("C", "B"), 
    character(0), "C", "B"), values2 = list("C", "E", "C", 
    "C", "C", "C", c("D", "A"), c("D", "A"), "D", "D", "D", "D", 
    "A", "E", "E", "A", "A", "A", "B", "A", "A", "A", "A", "D", 
    "E", "E", "A", "E", "E", character(0), "B", "B", "C", "C", 
    "C", "C", "C", "C", c("E", "A"), c("E", "A"), c("E", "A"), 
    c("E", "A"), c("C", "A"), c("C", "A"), c("C", "A"), c("C", 
    "A"), "E", c("E", "D"), c("E", "D"), "B", "E", "E", "A", 
    "A", "B", "B", "B", "B", "B", "D", "D", c("C", "B"), c("C", 
    "B"), c("C", "B"), c("C", "B"), "B", c("C", "A"), character(0), 
    "A", "B", "B", "B", "B", "B", "C", "C", c("E", "D"), c("E", 
    "D"), c("E", "D"), c("E", "D"), "E", "E", character(0), character(0), 
    "B", "E", "A", "C", "B", "C", "A", "C", "C", "C", "C", "C", 
    "A", "A", "A", "A", "A", "D", "B", "A", "C", "A", "A", "A", 
    "C", "A", "A", "B", "D", "D", "E", "E", "E", "E", character(0), 
    character(0), "C", "B", "B", "B", "B", "B", "E", "D", c("C", 
    "E"), c("C", "E"), "D", "D", "C", "C", "C", "C", "C", "C", 
    "C", "D", "E", "E", "B", "B", "C", "C", "B", "B", "E", "B", 
    "B", "B", "B", "B", "B", "E", "A", "B", "B", "A", "A", "A", 
    "D", "D", c("D", "A"), c("D", "A"), c("D", "B"), c("D", "B"
    ), "E", "E", "E", "E", "E", "E", "E", "D", "D", "E", "E", 
    "A", "A", "A", "A", "A", "D", "D", c("B", "A"), c("B", "A"
    ), "C", character(0), character(0), "B", "E", "E", "B", c("E", 
    "B"), "A", "A", "B", "B", "D", "D", "A", "A", "A", "A", "C", 
    "C", "C", "C", "B", "B", "A", "A", "B", "B", "A", "E", "C", 
    "C", "D", "D", "D", c("C", "E"), "D", "D", "D", "D", "E", 
    c("E", "A"), "E", character(0), character(0), "A", "D", "D", 
    c("D", "A"), c("D", "A"), c("D", "A"), c("D", "A"), c("D", 
    "A"), c("D", "A"), c("D", "A"), c("D", "A"), "B", "C", "C", 
    "C", "C", "B", "B", c("C", "E"), c("C", "E"), "E", "C", "C", 
    "C", c("E", "D", "B", "A"), c("E", "D", "B", "A"), "A", "A", 
    "A", "A", c("C", "A"), c("C", "A"), c("C", "A"), "E", "E", 
    "A", "C", "C", c("E", "D"), c("E", "D"), "A", "A", "A", "A", 
    "A", "A", "A", "A", "D", "E", c("C", "D"), "E", character(0), 
    character(0), character(0), "D", "D", character(0), "A", 
    "B", c("D", "B"), c("D", "B"), c("D", "B"), c("D", "B"), 
    "D", "D", "D", "E", "E", "D", "D", "B", "B", "B", "E", "D", 
    "C", "D", "C", "C", "E", "E", "A", character(0), "B", "B", 
    "B", "B", "B", "B", "B", "A", "A", "C", "C", "C", "D", "D", 
    "D", "D", "D", "D", "D", "B", "A", "B", "B", "D", "A", "A", 
    "A", "A", "D", "D", "E", "E", "B", character(0), character(0), 
    character(0), "C", "C", "C", "B", "B", "A", "D", c("C", "B"
    ), "D", "D", "C", "C", character(0), "D", "D", "D", "D", 
    c("B", "A"), "E", "A", "A", character(0), "E", "C", "B", 
    "C", "C", "C", "C", "E", "E", "D", "C", "C", "E", "E", "E", 
    "E", "E", "E", "E", "A", "B", c("C", "E", "D", "B", "A"), 
    c("C", "E", "D", "B", "A"), "D", "E", "E", "B", "B", character(0), 
    character(0), "D", "D", "C", "D", "D", "E", "E", "E", "E", 
    "E", c("D", "B"), "B", "B", character(0), "D", "D", "D", 
    "D", "D", "D", "C", "E", "E", "E", c("E", "B"), c("E", "B"
    ), "E", "E", "D", "D", "B", c("E", "A"), c("E", "A"), c("C", 
    "D"), c("C", "D"), c("C", "B"), c("C", "B"), "C", "C", "B")), row.names = c(NA, 
445L), class = "data.frame")

我想拆分这些数据,以便每个值都有自己的列:

       1      2      3     4      5
     <chr> <chr>  <chr>  <chr>  <chr>
1      A
2            B
3    
4                   C
5      A            C
6                          D
7            B      C
8                          D      E

然后,最终,将数据整理成整齐的格式,以便按列轻松过滤:

       A      B      C     D     E
    <logi> <logi> <logi> <logi> <logi>
1    TRUE  FALSE  FALSE  FALSE  FALSE
2    FALSE TRUE   FALSE  FALSE  FALSE
3    FALSE FALSE  FALSE  FALSE  FALSE
4    FALSE FALSE  TRUE   FALSE  FALSE
5    TRUE  FALSE  TRUE   FALSE  FALSE
6    FALSE FALSE  FALSE  TRUE  FALSE
7    FALSE TRUE   TRUE   FALSE  FALSE
8    FALSE FALSE  FALSE  TRUE   TRUE

最后一步应该很简单,变异,这是我无法弄清楚的分裂。我知道 tidyrseparateunnest_wider,但据我所知,不要让我控制向量被分成哪些列。

标签: rtidyrtibble

解决方案


假设您的数据是这样的:

df <- structure(list(values = list("A", "B", character(0), "C", c("A", 
"C"), "D", c("B", "C"), c("D", "E"))), 
 row.names = c(NA, -8L), class = "data.frame")

你可以做 :

library(dplyr)
library(tidyr)

df %>%
  mutate(row = row_number()) %>%
  unnest(values) %>%
  complete(row = 1:max(row)) %>%
  mutate(val = TRUE) %>%
  pivot_wider(names_from = values, values_from = val, values_fill = FALSE) %>%
  dplyr::select(-`NA`, -row)

#    A     B     C     D     E    
#  <lgl> <lgl> <lgl> <lgl> <lgl>
#1 TRUE  FALSE FALSE FALSE FALSE
#2 FALSE TRUE  FALSE FALSE FALSE
#3 FALSE FALSE FALSE FALSE FALSE
#4 FALSE FALSE TRUE  FALSE FALSE
#5 TRUE  FALSE TRUE  FALSE FALSE
#6 FALSE FALSE FALSE TRUE  FALSE
#7 FALSE TRUE  TRUE  FALSE FALSE
#8 FALSE FALSE FALSE TRUE  TRUE 

推荐阅读