dplyr中sd函数na.rm=TRUE失效,单值标准差显示NA求助
问题原因
R自带的sd()函数,当输入的向量只有1个有效值时,不管你设没设na.rm=TRUE,都会返回NA。这是因为样本标准差的计算公式里,分母是n-1(n是数据点数量),当n=1时分母为0,数学上没法计算,所以函数直接返回NA——na.rm参数的作用只是移除向量里的NA值,管不了单值的情况。
解决方法
给你三种实用的解决思路:
1. 自定义一个能处理单值的标准差函数
自己写个小函数,当输入数据只有1个点时返回0,其他情况用原生sd()计算:
my_sd <- function(x, na.rm = FALSE) { # 先移除NA(如果需要) if (na.rm) x <- na.omit(x) # 数据点数量<=1时返回0,否则计算标准差 if (length(x) <= 1) return(0) sd(x) }
如果是用dplyr分组计算的话,直接替换原来的sd()就行:
library(dplyr) # 假设你的原始数据是raw_data,value是要计算的列 raw_data %>% group_by(Family) %>% summarise( count = n(), mean = mean(value, na.rm = TRUE), sd = my_sd(value, na.rm = TRUE) )
2. 直接修正已有的结果表
如果你已经得到了像n11.stat这样的表格,直接用ifelse把count=1的行的NA替换成0:
n11.stat <- n11.stat %>% mutate(sd = ifelse(count == 1, 0, sd))
运行之后,所有单值分组的sd就会变成0,其他分组保持原来的结果。
3. 用第三方包的现成函数
比如DescTools包的Sd()函数,默认会把单值的标准差返回为0,不需要额外处理:
library(DescTools) # 分组计算时直接用 raw_data %>% group_by(Family) %>% summarise( count = n(), mean = mean(value, na.rm = TRUE), sd = Sd(value, na.rm = TRUE) )
使用前需要先安装包:install.packages("DescTools")。
内容的提问来源于stack exchange,提问作者Katherine Chau
相关产品推荐
相关产品推荐

