[英]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.