【问题标题】:Conditionally sorting/mutating items from nested (character) lists into new columns in R有条件地将嵌套(字符)列表中的项目排序/变异到 R 中的新列中
【发布时间】:2020-01-28 00:20:57
【问题描述】:

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

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是类字符,每个数字代表一种棋子:

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

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

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

【问题讨论】:

    标签: r conditional-statements nested-lists dplyr


    【解决方案1】:

    我们可以使用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
    

    【讨论】:

    • 非常感谢@akrun - 这正是我想要的。易于遵循,工作起来就像一个魅力!
    【解决方案2】:

    我们可以使用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
    

    【讨论】:

    • 非常感谢@Ronak Shah - 这也很有效!我将 akrun 的答案标记为正确,因为我喜欢使用 tidyverse 并能够跟踪导致结果的步骤。 splitstackshape 是一个非常有趣的包,再次感谢您向我介绍它!
    猜你喜欢
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 2014-08-03
    相关资源
    最近更新 更多