如何用R语言按地点计算多列变量各得分的占比?
问题描述
现有如下R数据集:
location = rep(c("A", "B", "C", "D"), times = c(4, 6, 3, 7)) ID = (1:20) Var1 = rep(c(0,2,1,1,0), times = 4) Var2 = rep(c(2,1,1,0,2), times = 4) Var3 = rep(c(1,1,0,2,0), times = 4) df=as.data.frame(cbind(location, ID, Var1, Var2, Var3))
需求是按location分组,统计每个变量(Var1/Var2/Var3)中得分0、1、2的出现次数,或直接计算各得分的占比。
尝试过编写统计各得分的函数:
score0 = function(a){sum(a==0)} score1 = function(a){sum(a==1)} score2 = function(a){sum(a==2)}
并结合dplyr的group_by使用lapply,但未得到预期结果,也无法将单变量分组占比的方案扩展到多变量场景。
解决方案
第一步:修正数据集类型
原代码中cbind会将所有列转换为字符型,导致后续数值统计出错,建议直接用data.frame创建数据集,保留数值类型:
location = rep(c("A", "B", "C", "D"), times = c(4, 6, 3, 7)) ID = (1:20) Var1 = rep(c(0,2,1,1,0), times = 4) Var2 = rep(c(2,1,1,0,2), times = 4) Var3 = rep(c(1,1,0,2,0), times = 4) # 直接创建数据框,避免类型转换问题 df <- data.frame(location, ID, Var1, Var2, Var3)
方法1:统计各得分出现次数
使用tidyverse工具将宽表转为长表,再按分组统计次数:
library(tidyverse) # 转长表,统一处理所有变量 count_result <- df %>% # 将Var1-Var3转为变量名-得分的长格式 pivot_longer(cols = starts_with("Var"), names_to = "variable", values_to = "score") %>% # 按地点、变量、得分分组统计次数 group_by(location, variable, score) %>% count(name = "count") %>% ungroup() print(count_result)
方法2:计算各得分占比
在次数统计的基础上,按地点和变量分组计算占比:
proportion_result <- count_result %>% group_by(location, variable) %>% # 计算当前得分占该地点-变量总次数的比例 mutate(proportion = count / sum(count)) %>% ungroup() print(proportion_result)
补充说明
之前用group_by后直接lapply的问题在于:group_by返回的分组对象,lapply会遍历每一列而非按组处理变量;同时原数据集的数值列被转为字符型,导致sum(a==0)实际统计的是字符"0"的数量,与预期不符。
内容的提问来源于stack exchange,提问作者AlHu
相关产品推荐
相关产品推荐

