有条件地将嵌套(字符)列表中的项目排序/变异为R中的新列

问题描述 投票:0回答:2

我具有从调查表创建的以下数据框:

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

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

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

我想根据ex_df$type列中的字符为每种表示存在/不存在的棋子创建一个单独的列,其中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

以表格形式:

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

[到目前为止,我尝试使用ex_df$typestrsplit()转换为具有数值的列表,然后将嵌套的lapply()与dplyr的mutate()when_case()结合使用,但这没有用。我在嵌套列表上遇到了麻烦,所以也许我的方法不正确?

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

r dplyr conditional-statements nested-lists mutate
2个回答
0
投票

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

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

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
© www.soinside.com 2019 - 2024. All rights reserved.