首页 > 解决方案 > 从多项选择题的字符串变量中提取值的正确方法

问题描述

我有一个数据集,参与者可以同时选择多个选项(从 0 到 5)。结果,变量是一个字符串,看起来像

0145
0123
012345
234

(取决于他们做出了哪些选择)。

如果相应的值包含在字符串中,我需要添加将设置为 true 的列 (choice_0、choice_1、...、choice_5)。

现在我这样做,但我想知道是否有更漂亮的方式:

  df %>%mutate(source_0 = str_detect(knowledge_type, '0'),
         source_1 = str_detect(knowledge_type, '1'),
         source_2 = str_detect(knowledge_type, '2'),
         source_3 = str_detect(knowledge_type, '3'),
         source_4 = str_detect(knowledge_type, '4'),
         source_5 = str_detect(knowledge_type, '5')
         )

标签: rdplyrtidyverse

解决方案


您可以使用splitstackshape::cSplit_ewhich 将返回二进制值。

res <- splitstackshape::cSplit_e(df, 'knowledge_type', 
            type = 'character', sep = '', fill = 0)

res
#  knowledge_type knowledge_type_0 knowledge_type_1 knowledge_type_2
#1           0145                1                1                0
#2           0123                1                1                1
#3         012345                1                1                1
#4            234                0                0                1

#  knowledge_type_3 knowledge_type_4 knowledge_type_5
#1                0                1                1
#2                1                0                0
#3                1                1                1
#4                1                1                0

如果您需要逻辑值,您可以添加 -

res[-1] <- res[-1] > 0
res

#  knowledge_type knowledge_type_0 knowledge_type_1 knowledge_type_2
#1           0145             TRUE             TRUE            FALSE
#2           0123             TRUE             TRUE             TRUE
#3         012345             TRUE             TRUE             TRUE
#4            234            FALSE            FALSE             TRUE

#  knowledge_type_3 knowledge_type_4 knowledge_type_5
#1            FALSE             TRUE             TRUE
#2             TRUE            FALSE            FALSE
#3             TRUE             TRUE             TRUE
#4             TRUE             TRUE            FALSE

一种tidyverse使用方式map_dfc-

library(tidyverse)

bind_cols(df, map_dfc(as.character(0:5), ~df %>% 
          transmute(!!paste0('source', .x) := str_detect(knowledge_type, .x))))

#  knowledge_type source0 source1 source2 source3 source4 source5
#1           0145    TRUE    TRUE   FALSE   FALSE    TRUE    TRUE
#2           0123    TRUE    TRUE    TRUE    TRUE   FALSE   FALSE
#3         012345    TRUE    TRUE    TRUE    TRUE    TRUE    TRUE
#4            234   FALSE   FALSE    TRUE    TRUE    TRUE   FALSE

推荐阅读