R语言分组计算均值与众数问题:众数返回numeric类型异常
解决R语言分组计算分类变量众数的问题
首先得提个小细节:你提供的原始数据框存在列长度不匹配的问题,R无法创建这样的数据框(code有10个元素,但idp、p_origin、returnee的长度分别是2、5、2)。我先帮你修正为符合逻辑的结构,保证每行对应一个观测值:
df <- data.frame( code = c(1,1,1,1,1,1,2,2,2,2), idp = c(120,140,120,140,120,140,120,140,120,140), p_origin = c("yes","yes","no","yes","yes","yes","no","no","yes","no"), returnee = c("yes","no","yes","no","yes","no","yes","no","yes","no") )
核心问题:R自带的mode()不是统计众数
你遇到众数返回"numeric"的问题,是因为R原生的mode()函数根本不是用来计算统计意义上的众数——它的作用是返回对象的存储类型(比如数值型、字符型),所以必须自定义函数来实现分类变量的众数计算。
自定义逻辑完成分组计算
我分两种方式帮你实现需求,你可以选顺手的来:
方式一:统一自定义函数(更复用)
library(dplyr) # 自定义众数函数,支持returnee的特殊规则 get_custom_mode <- function(x, is_returnee = FALSE) { tab <- table(x) max_count <- max(tab) modes <- names(tab)[tab == max_count] if (is_returnee) { # 针对returnee:如果yes和no次数相等,返回no_sense if (length(modes) == 2 && all(c("yes", "no") %in% modes)) { return("no_sense") } else { return(modes[1]) } } else { # 普通情况:返回第一个出现的众数(若有多个) return(modes[1]) } } # 分组计算所有指标 output_df <- df %>% group_by(code) %>% mutate( average_idp = mean(idp), Most_frequent_origin = get_custom_mode(p_origin), Most_frequent_returnee = get_custom_mode(returnee, is_returnee = TRUE) ) %>% ungroup()
方式二:直接在mutate中处理(更直观)
如果不想单独写函数,也可以直接在分组计算里针对不同列做逻辑判断:
output_df <- df %>% group_by(code) %>% mutate( # 计算idp平均值 average_idp = mean(idp), # 计算p_origin的众数 Most_frequent_origin = { tab <- table(p_origin) names(tab)[which.max(tab)] }, # 计算returnee的众数,特殊处理相等情况 Most_frequent_returnee = { tab <- table(returnee) if (tab["yes"] == tab["no"]) { "no_sense" } else { names(tab)[which.max(tab)] } } ) %>% ungroup()
验证结果
运行后得到的output_df完全符合你的需求:
- code=1组:
average_idp=130,Most_frequent_origin="yes",Most_frequent_returnee="no_sense" - code=2组:
average_idp=130,Most_frequent_origin="no",Most_frequent_returnee="no_sense"
内容的提问来源于stack exchange,提问作者MaxMiak
相关产品推荐
相关产品推荐

