如何从多选种族问卷数据中获取单一类别百分比分布?
问题:从多选种族的组合类别中统计单一种族占比
我运行以下代码统计样本种族分布:
dataset %>% group_by(ethnicity) %>% summarise(percent = 100 * n()/nrow(datset))
(注:原代码存在拼写错误,datset应为dataset)
但因问卷允许受试者多选种族类别,结果显示的是组合类别占比(示例如下):
1 "[\"Aboriginal or Torres Strait Islander\",\"Caucasian\",\"Asian (inc. Indian subcontinent)\"]" 0.364 2 "[\"Aboriginal or Torres Strait Islander\",\"Caucasian\"]" 0.0910 3 "[\"Aboriginal or Torres Strait Islander\"]" 0.910 4 "[\"African\"]" 0.637 5 "[\"Asian (inc. Indian subcontinent)\"]" 0.0910 9 "[\"Caucasian\",\"Latino/Hispanic\"]" 0.182 10 "[\"Caucasian\",\"Middle Eastern\"]" 0.273 11 "[\"Caucasian\",\"Not listed\"]" 0.182
现需获取单一种族类别(如Caucasian、African等)的百分比分布,求最优高效实现方法。
解决方案
针对多选产生的组合种族字符串,有两种高效实现方式,均基于tidyverse工具链:
方法1:JSON解析法(鲁棒性最强)
由于种族列是标准JSON格式的字符串,用jsonlite包解析最稳妥,能避免种族名称含特殊字符导致的拆分错误:
library(tidyverse) library(jsonlite) dataset %>% # 将JSON字符串转为种族列表 mutate(ethnicity = map(ethnicity, fromJSON)) %>% # 拆分列表为单独行,每个种族对应一行 unnest(ethnicity) %>% # 按单一种族分组统计 group_by(ethnicity) %>% # 计算占比:选择该种族的样本数/总样本数*100(多选场景下占比总和会超100%) summarise(percent = 100 * n() / nrow(dataset)) %>% # 可选:按占比降序排列 arrange(desc(percent))
方法2:字符串拆分法(无需额外包)
如果不想加载jsonlite,可以直接通过字符串处理拆分组合:
library(tidyverse) dataset %>% # 移除字符串前后的方括号和引号 mutate(ethnicity = str_remove_all(ethnicity, '^\\["|\\"]$')) %>% # 按","拆分字符串为多行 separate_rows(ethnicity, sep = '","') %>% group_by(ethnicity) %>% summarise(percent = 100 * n() / nrow(dataset)) %>% arrange(desc(percent))
说明
两种方法的核心逻辑一致:将每个多选组合拆分为单独的种族条目,再统计每个种族被选择的样本数占总样本的百分比。由于是多选数据,最终所有种族的百分比之和会超过100%,这是正常现象。
内容的提问来源于stack exchange,提问作者Louis
相关产品推荐
相关产品推荐

