如何统计非NA单元格数量并按姓名计算剔除NA后的平均得分
解决按姓名计算平均得分的问题
嘿,我来帮你搞定这个统计非NA值数量并计算平均分的需求!其实不用分开单独统计数量,咱们可以直接结合求和(忽略NA)和计数,或者用更简洁的函数一步到位算出平均分。下面给你几种实用的方法:
方法一:基础R手动计算总和与非NA数量
这种方式适合你已经有求和逻辑,想单独统计非NA数量的场景:
# 你的原始数据 names <- c("d", "e", "f", "g") score.a.ALL <- c(1, 2, NA, 3) score.b.ALL <- c(NA, 4, 5, 6) score.c.ALL <- c(NA, NA, NA, 1) dat <- data.frame(names, score.a.ALL, score.b.ALL, score.c.ALL) # 1. 统计每行非NA得分的数量:!is.na()把非NA转为TRUE(1),NA转为FALSE(0),rowSums求和得到数量 dat$non_na_count <- rowSums(!is.na(dat[, -1])) # 排除第一列names,计算所有得分列的非NA数量 # 2. 计算每行得分总和(自动忽略NA) dat$total_score <- rowSums(dat[, -1], na.rm = TRUE) # 3. 计算平均分:总和除以非NA数量 dat$avg_score <- dat$total_score / dat$non_na_count
运行后你会得到包含平均分的完整数据框,如果某行全是NA,non_na_count会是0,这时候avg_score会变成NaN,你可以用ifelse(dat$non_na_count == 0, NA, dat$total_score / dat$non_na_count)来把这种情况转为NA。
方法二:用apply函数一步算平均分
更简洁的方式,直接对每行应用mean()函数并忽略NA,不用分开计算总和和数量:
dat$avg_score <- apply(dat[, -1], 1, function(x) mean(x, na.rm = TRUE))
这里apply(dat[, -1], 1, ...)表示对数据框的每行(第二个参数1代表行)执行后面的函数,mean(x, na.rm = TRUE)会自动忽略NA值计算平均值。
方法三:用tidyverse/dplyr的管道风格(适合数据处理流程)
如果你习惯用tidyverse的语法,用rowwise()结合c_across()可以轻松实现:
library(dplyr) dat <- dat %>% rowwise() %>% # 按行处理 mutate(avg_score = mean(c_across(starts_with("score")), na.rm = TRUE)) %>% # 对所有以score开头的列计算平均分 ungroup() # 取消按行分组
这种方式可读性强,尤其当你有后续数据处理步骤时,管道操作会很顺手。
内容的提问来源于stack exchange,提问作者Emma Kortemeier
相关产品推荐
相关产品推荐

