You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用dplyr的summarise()和across()计算变异系数时出错

错误原因

你写的(sd/mean)*100是试图将两个函数对象sd()和mean()做除法运算,这显然不符合语法要求——across的第二个参数需要是针对单列数据的函数,而非直接用函数名做算术操作。同时,在同一个summarise()调用里,后续的across无法引用前面生成的_mean和_sd列,因为across始终是对分组后的原始列进行操作。


解决方案

方案1:单across一次性计算所有统计量

最简洁的方式,对每列同时计算均值、标准差、变异系数,避免跨步骤引用问题:

df2 <- df %>% 
  group_by(group) %>% 
  summarise(
    across(where(is.numeric), 
           list(
             mean = ~mean(., na.rm = TRUE),
             sd = ~sd(., na.rm = TRUE),
             cv = ~100 * (sd(., na.rm = TRUE)/mean(., na.rm = TRUE))
           ),
           .names = "{col}_{fn}")
  )

这里用list()封装三个匿名函数,.代表当前处理的列,.names参数自动生成带后缀的列名。

方案2:先算均值/标准差,再用mutate生成CV

如果偏好分步计算,先得到均值和标准差列,再基于这些列计算CV:

library(stringr)

df2 <- df %>% 
  group_by(group) %>% 
  summarise(
    across(where(is.numeric), mean, na.rm = TRUE, .names = "{col}_mean"),
    across(where(is.numeric), sd, na.rm = TRUE, .names = "{col}_sd")
  ) %>% 
  mutate(
    across(ends_with("_sd"), 
           ~100 * (. / get(str_replace(cur_column(), "_sd", "_mean"))),
           .names = "{str_remove(col, '_sd')}_cv")
  )

通过cur_column()获取当前列名,替换后缀匹配对应的均值列,完成CV计算。

方案3:自定义CV函数(处理边界情况)

先编写一个带异常处理的CV函数,再在across中调用,可避免均值为0时的除以0报错:

# 自定义CV函数,均值为0时返回NA
calc_cv <- function(x, na.rm = TRUE) {
  m <- mean(x, na.rm = na.rm)
  if (m == 0) return(NA_real_)
  100 * (sd(x, na.rm = na.rm) / m)
}

# 调用自定义函数
df2 <- df %>% 
  group_by(group) %>% 
  summarise(
    across(where(is.numeric), mean, na.rm = TRUE, .names = "{col}_mean"),
    across(where(is.numeric), sd, na.rm = TRUE, .names = "{col}_sd"),
    across(where(is.numeric), calc_cv, na.rm = TRUE, .names = "{col}_cv")
  )

内容的提问来源于stack exchange,提问作者Bleras

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 06:35:18