特定列按行众数计算:以最新记录打破平局的实现方案
问题:为数据集新增按行计算的「忽略NA的最新众数」列
需求说明:
- 数据集每行对应一名参与者,包含最多4个编码列(
FirstCoder到FourthCoder,编码顺序从最早到最新) - 需要新增一列,返回每行编码列的众数(忽略NA值);若多个值出现次数相同(平局),选择**编码时间最晚(列位置最靠右)**的那个众数
示例数据集:
fakeData = data.frame(id = 1:3, Condition = c("Essay", "Chat", "Chat"), FirstCoder = c("NA","Essay","Essay"), SecondCoder = c("NA","Chat","Essay"), ThirdCoder = c("Essay","Chat","Chat"), FourthCoder = c("Essay","NA","Chat"))
期望结果:新增列MostRecentModalCode的值为c("Essay", "Chat", "Chat")
问题分析
之前尝试的apply方法存在逻辑错误:
ModalCode1错误地统计了列名的频率,而非编码值- 常规
Mode函数无法处理平局时选择最新值的需求
解决方案
步骤1:预处理数据(将字符串"NA"转为真实缺失值)
原数据中的"NA"是字符型字符串,需先转为R的原生缺失值NA:
fakeData[fakeData == "NA"] <- NA
步骤2:自定义最新众数计算函数
编写函数实现「忽略NA+平局取最新」的逻辑:
get_most_recent_mode <- function(row_values) { # 过滤缺失值 non_na_vals <- na.omit(row_values) if (length(non_na_vals) == 0) return(NA) # 统计各编码值的出现次数 val_counts <- table(non_na_vals) max_count <- max(val_counts) # 筛选所有众数候选(出现次数等于最大值的编码) mode_candidates <- names(val_counts[val_counts == max_count]) # 处理唯一众数的情况 if (length(mode_candidates) == 1) { return(mode_candidates) } else { # 反向遍历编码值(从最新到最早),返回第一个匹配的候选值 for (val in rev(row_values)) { if (!is.na(val) && val %in% mode_candidates) { return(val) } } } }
步骤3:将函数应用到数据集
选择编码列并按行执行函数:
fakeData$MostRecentModalCode <- apply( fakeData[, c("FirstCoder", "SecondCoder", "ThirdCoder", "FourthCoder")], 1, get_most_recent_mode )
验证结果
执行后查看数据集:
> fakeData id Condition FirstCoder SecondCoder ThirdCoder FourthCoder MostRecentModalCode 1 1 Essay <NA> <NA> Essay Essay Essay 2 2 Chat Essay Chat Chat <NA> Chat 3 3 Chat Essay Essay Chat Chat Chat
结果完全符合预期。
内容的提问来源于stack exchange,提问作者Nick Byrd
相关产品推荐
相关产品推荐

