如何将R中关联多选项的调查数据框转换为长格式?
问题分析与解决
错误原因
你在pivot_longer中使用matches(Q1)的写法有误:matches()函数需要接收固定的正则表达式字符串,但Q1是数据框的列,每行对应不同的颜色值,属于逐行变化的向量,无法作为统一的选择规则,因此触发了"selections can't have missing values"的报错。
另外,你用separate_rows(Q1, sep = ",")拆分时,会导致Q1的颜色值带有前导空格(比如" Red"),后续匹配Q2列名时会失败,需要修正分隔符为, (逗号加空格)。
正确实现方法
方法1:先整理Q2为长格式,再关联拆分后的Q1
这种方法更直观,适合后续扩展到Q3-Q9的场景:
library(tidyverse) # 原始数据 df <- data.frame( ID = 1:3, Q1 = c("Purple, Red, Blue", "Red, Blue, Yellow", "Red"), "Q2: Is it your favorite color? - Purple" = c("Average", NA, NA), "Q2: Is it your favorite color? - Red" = c("No", "No", "Average"), "Q2: Is it your favorite color? - Blue" = c("Yes", "No", NA), "Q2: Is it your favorite color? - Yellow" = c(NA, "Average", NA) ) # 1. 拆分Q1为多行,去除颜色值的前后空格 df_q1_split <- df %>% separate_rows(Q1, sep = ", ") %>% mutate(Q1 = trimws(Q1)) # 2. 将所有Q2列转成长格式,提取列名中的颜色 df_q2_long <- df %>% select(ID, starts_with("Q2")) %>% pivot_longer( cols = -ID, names_to = "temp_col", values_to = "Q2" ) %>% # 从Q2列名中提取颜色(匹配"- "后的内容) mutate(Q1 = str_extract(temp_col, "(?<= - ).+$")) %>% select(ID, Q1, Q2) %>% drop_na(Q2) # 剔除无回答的行 # 3. 合并数据,只保留Q1选中颜色对应的Q2回答 final_result <- df_q1_split %>% select(ID, Q1) %>% left_join(df_q2_long, by = c("ID", "Q1")) print(final_result)
方法2:用rowwise逐行匹配
适合快速处理单组Q2的场景,逐行选择对应Q1的Q2列:
library(tidyverse) final_result <- df %>% separate_rows(Q1, sep = ", ") %>% mutate(Q1 = trimws(Q1)) %>% rowwise() %>% # 匹配当前行Q1对应的Q2列,提取值 mutate(Q2 = pull(cur_data(), matches(str_c("Q2.*- ", Q1)))) %>% ungroup() %>% select(ID, Q1, Q2) print(final_result)
两种方法都会输出你需要的长格式结果:
# A tibble: 7 × 3 ID Q1 Q2 <int> <chr> <chr> 1 1 Purple Average 2 1 Red No 3 1 Blue Yes 4 2 Red No 5 2 Blue No 6 2 Yellow Average 7 3 Red Average
内容的提问来源于stack exchange,提问作者Ekd
相关产品推荐
相关产品推荐

