如何按UserID分组计算DataFrame中Answer列的众数?
按UserID分组计算众数的实现方案
首先需要自定义一个众数计算函数,因为R语言没有内置的众数统计函数,以下是基础版本的实现:
find_mode <- function(x) { # 移除NA值(若需保留NA可删除此行) x <- na.omit(x) # 统计各答案的出现频率 freq_table <- table(x) # 提取最高频率值 max_freq <- max(freq_table) # 返回频率最高的答案(若有多个众数,仅取第一个) as.numeric(names(freq_table[freq_table == max_freq]))[1] }
方法一:Base R(与你当前用的aggregate语法兼容)
假设你的DataFrame中Answer列是第3列,直接复用aggregate框架调用自定义函数即可:
answers_mode <- aggregate(DF[, 3], list(UserID = DF$UserID), find_mode) # 重命名列名匹配需求格式 colnames(answers_mode) <- c("UserID", "AnsMod")
方法二:Tidyverse(dplyr分组语法)
如果你更习惯用dplyr的分组操作,步骤如下:
- 先安装并加载dplyr包:
install.packages("dplyr") library(dplyr)
- 分组计算众数:
answers_mode <- DF %>% group_by(UserID) %>% summarise(AnsMod = find_mode(Answer), .groups = "drop")
进阶:处理多众数场景
如果某个用户的答案存在多个出现频率相同的众数,可修改函数返回所有众数:
find_mode_all <- function(x) { x <- na.omit(x) freq_table <- table(x) max_freq <- max(freq_table) as.numeric(names(freq_table[freq_table == max_freq])) }
此时返回的AnsMod为列表类型,若需展开为多行可使用tidyr包的unnest:
install.packages("tidyr") library(tidyr) answers_mode <- DF %>% group_by(UserID) %>% summarise(AnsMod = list(find_mode_all(Answer)), .groups = "drop") %>% unnest(AnsMod)
内容的提问来源于stack exchange,提问作者pillypum
相关产品推荐
相关产品推荐

