有条件地将嵌套(字符)列表中的 sorting/mutating 项放入 R 中的新列中

Conditionally sorting/mutating items from nested (character) lists into new columns in R

我有以下根据问卷创建的数据框:

id <- c(1, 2, 3, 4, 5)
type <- c("1,2,3", "2", "2,3,4", "4", "1")
ex_df <- data.frame(id, type, stringsAsFactors=F)

ex_df$type是class字,每个数字代表一种棋子:

1 = pawn
2 = rook
3 = knight
4 = bishop

我想根据 ex_df$type 列中的字符为每种类型的棋子创建一个单独的列,指示 present/not 存在,其中 1 表示棋子是在列表中,0 它不在列表中。

最终数据框应如下所示:

'data.frame':   5 obs. of  6 variables:
 $ id    : num  1 2 3 4 5
 $ type  : chr  "1,2,3" "2" "2,3,4" "4" ...
 $ pawn  : num  1 0 0 0 1
 $ rook  : num  1 1 1 0 0
 $ knight: num  1 0 1 0 0
 $ bishop: num  0 0 1 1 0

在table形式中:

id  type pawn rook knight bishop
 1 1,2,3    1    1      1      0
 2     2    0    1      0      0
 3 2,3,4    0    1      1      1
 4     4    0    0      0      1
 5     1    1    0      0      0

到目前为止,我尝试使用 strsplit()ex_df$type 转换为包含数值的列表,然后将嵌套的 lapply() 与 dplyr 的 mutate() 结合使用 when_case() 但这没有用。我在使用嵌套列表时遇到问题,所以我的方法可能不正确?

我在发布之前进行了彻底的搜索,但感觉我在这里遗漏了一些非常明显的东西,比如我不知道的函数正是这样做的。也许我没有在正确的方向寻找解决方案?

我们可以使用 splitstackshape 中的 cSplit_etype 中创建逗号分隔值的二进制表示,然后更改列名。

output <- splitstackshape::cSplit_e(ex_df, "type", type = "character", fill = 0)
names(output)[-c(1, 2)] <- c('pawn', 'rook', 'knight', 'bishop')
output

#  id  type pawn rook knight bishop
#1  1 1,2,3    1    1      1      0
#2  2     2    0    1      0      0
#3  3 2,3,4    0    1      1      1
#4  4     4    0    0      0      1
#5  5     1    1    0      0      0

我们可以使用tidyverse来做到这一点

library(dplyr)
library(tidyr)
ex_df %>% 
   separate_rows(type, convert = TRUE) %>% 
   mutate(type = c('pawn', 'rook', 'knight', 'bishop')[type], n = 1) %>% 
   pivot_wider(names_from = type, values_from = n, values_fill = list(n = 0)) %>% 
   left_join(ex_df)%>% 
   select(names(ex_df), everything())
#   id  type pawn rook knight bishop
#1  1 1,2,3    1    1      1      0
#2  2     2    0    1      0      0
#3  3 2,3,4    0    1      1      1
#4  4     4    0    0      0      1
#5  5     1    1    0      0      0