繁体   English   中英

将多个二分变量(来自多项选择题)转换为单个选择一个变量的 R 代码

[英]R code to transform several dichotomous variables (coming from a multiple choice question) to a single select one variable

在一项调查中一个多项选择题,我的数据中有几个二分变量,我想将这些变量转换为单个选择一个变量(因为调查中的大多数受访者没有选择多个选项)。

我在数据框 (df) 中有变量,名称如下 var1、var2、....、var195。 我编写了以下完美运行的代码:

df<-df %>% mutate(
newvar = case_when(
  var1 == "yes" ~ "option1",
  var2 == "yes" ~ "option2",
  var3 == "yes" ~ " option3",
  var4 == "yes" ~ "option4",
  and so on)
)

但是,这很乏味,因为我应该有 195 行。 我尝试编写以下函数(试图简化和加速我的代码)但它不起作用。

multichoice_to_one<-function(df,pat,charvec){ 
# df is the dataframe with the data to handle 
# pat is the pattern to look into in the names of variables in this case
# "var"
# charvec is the (character) vector of the options
      for (i in 1:length(charvec)){df<-df %>% cat(str_c(pat,i))=="yes" ~ charvec[i]}}

任何人都可以帮忙吗?

对于这些类型的问题,使用“长”数据通常是最容易的,因此pivot_longer是您的朋友! 这是一个解决方案(它不使用您开始使用的函数方法)。

基本上对于每个调查回复,它会在您的相关列中查找第一个“是”回复。

library(tidyverse)

# Create some dummy data with 4 columns to look in, plus some extra columns
n_responses <- 100
df <- tibble(
  id = 1:n_responses,
  var1 = sample(c("yes", "no"), n_responses, TRUE),
  var2 = sample(c("yes", "no"), n_responses, TRUE),
  var3 = sample(c("yes", "no"), n_responses, TRUE),
  var4 = sample(c("yes", "no"), n_responses, TRUE),
  othervar1 = sample(LETTERS, n_responses, TRUE),
  othervar2 = sample(LETTERS, n_responses, TRUE)
)

df <- df %>%
  # Turn the data from 'wide' to 'long'. Only pivots the 'varX' columns
  pivot_longer(cols = starts_with("var"), names_to = "question", values_to = "response") %>% 
  # Group by the response number (or any other unique ID for each response in your survey)
  group_by(id) %>% 
  # Sets `first_yes` to the question name if:
  #                         the person responded yes, and
  #                                             either it's the first row or we haven't seen any 'yes' responses previously
  mutate(first_yes = ifelse(response == "yes" & (row_number() == 1 | !lag(cumany(response == "yes"))), question, NA)) %>% 
  # Fill in the response name for all rows
  mutate(first_yes = max(first_yes, na.rm = TRUE)) %>% 
  ungroup() %>% 
  # Put the data back into the old format
  pivot_wider(names_from = question, values_from = response)

对于在相关列中没有任何“是”的任何行,您都会收到一条错误消息。 这些行将在指标列中包含NA

假设一个数据框是这样的:

# A tibble: 15 × 10
   V1    V2    V3    V4    V5    V6    V7    V8    V9    V10  
   <lgl> <lgl> <lgl> <lgl> <lgl> <lgl> <lgl> <lgl> <lgl> <lgl>
 1 FALSE FALSE FALSE FALSE FALSE TRUE  FALSE FALSE FALSE TRUE 
 2 FALSE TRUE  FALSE TRUE  TRUE  FALSE TRUE  FALSE TRUE  TRUE 
 3 FALSE TRUE  TRUE  FALSE FALSE FALSE TRUE  FALSE TRUE  FALSE
 4 FALSE TRUE  TRUE  TRUE  FALSE TRUE  FALSE TRUE  TRUE  TRUE 
 5 FALSE TRUE  TRUE  TRUE  TRUE  FALSE TRUE  FALSE TRUE  TRUE 
 6 FALSE TRUE  FALSE TRUE  TRUE  TRUE  TRUE  FALSE TRUE  TRUE 
 7 TRUE  FALSE FALSE FALSE TRUE  FALSE TRUE  TRUE  FALSE TRUE 
 8 TRUE  FALSE TRUE  TRUE  FALSE TRUE  FALSE TRUE  TRUE  TRUE 
 9 FALSE FALSE FALSE TRUE  TRUE  TRUE  TRUE  TRUE  FALSE FALSE
10 TRUE  TRUE  TRUE  FALSE FALSE FALSE FALSE TRUE  TRUE  FALSE
11 TRUE  FALSE TRUE  TRUE  TRUE  FALSE FALSE TRUE  FALSE FALSE
12 TRUE  FALSE FALSE TRUE  TRUE  TRUE  FALSE FALSE TRUE  TRUE 
13 TRUE  FALSE FALSE TRUE  TRUE  FALSE FALSE TRUE  TRUE  TRUE 
14 TRUE  TRUE  FALSE TRUE  TRUE  FALSE TRUE  FALSE FALSE TRUE 
15 FALSE FALSE TRUE  FALSE FALSE TRUE  FALSE FALSE FALSE TRUE 

您可以简单地使用:

df %>%
    mutate(group = apply(., 1, function(row, ...){ first(which(row == TRUE)) }) %>% factor())
# A tibble: 15 × 11
   V1    V2    V3    V4    V5    V6    V7    V8    V9    V10   group
   <lgl> <lgl> <lgl> <lgl> <lgl> <lgl> <lgl> <lgl> <lgl> <lgl> <fct>
 1 FALSE FALSE FALSE FALSE FALSE TRUE  FALSE FALSE FALSE TRUE  6    
 2 FALSE TRUE  FALSE TRUE  TRUE  FALSE TRUE  FALSE TRUE  TRUE  2    
 3 FALSE TRUE  TRUE  FALSE FALSE FALSE TRUE  FALSE TRUE  FALSE 2    
 4 FALSE TRUE  TRUE  TRUE  FALSE TRUE  FALSE TRUE  TRUE  TRUE  2    
 5 FALSE TRUE  TRUE  TRUE  TRUE  FALSE TRUE  FALSE TRUE  TRUE  2    
 6 FALSE TRUE  FALSE TRUE  TRUE  TRUE  TRUE  FALSE TRUE  TRUE  2    
 7 TRUE  FALSE FALSE FALSE TRUE  FALSE TRUE  TRUE  FALSE TRUE  1    
 8 TRUE  FALSE TRUE  TRUE  FALSE TRUE  FALSE TRUE  TRUE  TRUE  1    
 9 FALSE FALSE FALSE TRUE  TRUE  TRUE  TRUE  TRUE  FALSE FALSE 4    
10 TRUE  TRUE  TRUE  FALSE FALSE FALSE FALSE TRUE  TRUE  FALSE 1    
11 TRUE  FALSE TRUE  TRUE  TRUE  FALSE FALSE TRUE  FALSE FALSE 1    
12 TRUE  FALSE FALSE TRUE  TRUE  TRUE  FALSE FALSE TRUE  TRUE  1    
13 TRUE  FALSE FALSE TRUE  TRUE  FALSE FALSE TRUE  TRUE  TRUE  1    
14 TRUE  TRUE  FALSE TRUE  TRUE  FALSE TRUE  FALSE FALSE TRUE  1    
15 FALSE FALSE TRUE  FALSE FALSE TRUE  FALSE FALSE FALSE TRUE  3 

我使用以下方法构建了上面的示例框架:

df = replicate(n=p, sample(c(TRUE, FALSE), size=n, replace=TRUE)) %>%
    as_tibble()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM