首页 > 解决方案 > R编码由分隔符连接的分类变量

问题描述

上下文

在我的数据框中,我有一列包含对餐厅消费替代品问题的固定回复。如果需要,受访者可以一次选择多个选项。

以下是此问题可供受访者使用的 9 个独特答案选项 -

#Unique responses to question
unique_vector = c('Bring food from home',
                  'Buy from a supermarket',
                  'Buy from deli, bakery, coffee, or sandwich shop',
                  'Go home',
                  'Go out to a fast food outlet',
                  'Order food from outside',
                  'Snack between meals',
                  'Go out to a full service restaurant',
                  'Skip the meal')

在对 10 位受访者进行调查后,生成的数据框如下所示 -

#Survey Dataframe
df= data.frame(
                          Id = c(1:10),

                          QUESTION=c(unique_vector[1],
                          paste0(unique_vector[1],',',unique_vector[2]),
                          paste0(unique_vector[1],',',unique_vector[2],',',unique_vector[2]),
                          paste0(unique_vector[4],',',unique_vector[5],',',unique_vector[1]),
                          paste0(unique_vector[3],',',unique_vector[1],',',unique_vector[9],',',unique_vector[7]),
                          paste0(unique_vector[5],',',unique_vector[6],',',unique_vector[8],',',unique_vector[1]),
                          unique_vector[3],
                          "",
                          paste0(unique_vector[5],',',unique_vector[6],',',unique_vector[8],',',unique_vector[1]),
                          "")
)

我的目标

我想分散该QUESTION列,使每个唯一响应都是数据框中的一个单独的列。

然后我想对这些响应进行编码,使它们记录为 1(没有响应为 0)。

我的尝试

我尝试在 R 中使用 one-hot 编码包。但我无法弄清楚如何修改我的代码以分离连接的响应。

#Attempt
library(onehot)
encoded_df = onehot(df[,2], stringsAsFactors=TRUE)

此处的任何输入将不胜感激。

标签: rone-hot-encoding

解决方案


我相当怀疑这是最简单的方法,但结果是正确的:

library(tidyverse)

unique_vector %>%
  str_c(collapse = ')|(') %>%
  str_c('(', ., ')') %>%
  str_extract_all(df$QUESTION, ., simplify = TRUE) %>%
  as.data.frame() %>%
  as_tibble() %>%
  mutate(Id = row_number()) %>%
  gather(x, key, V1:V4) %>%
  mutate(val = 1) %>%
  spread(key, val, fill = 0) %>%
  select(-c(x, V1)) %>%
  group_by(Id) %>%
  summarise_all(~if_else(sum(.) > 0, 1, 0))

如果分隔符与,(,也出现在答案中) 不同,则通过在此分隔符上拆分会更简单:

df %>%
  as_tibble() %>%
  mutate(QUESTION = map(QUESTION, ~str_split(.x, ',')[[1]] %>% unique)) %>%
  unnest() %>%
  mutate(val = 1) %>%
  spread(QUESTION, val, fill = 0) %>%
  select(-V1)

推荐阅读