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

在R中按组计算排除当前观测值的标准差

计算分组标准差时排除当前观测值的简便方法

当然有简便方法啦!用dplyr就能轻松实现,甚至有两种思路可以选——一种直观易懂适合小数据,另一种向量化操作适合大数据场景,我给你一步步拆解:

首先先把你的示例数据定义好:

df <- data.frame(
  country = c(rep("A",3), rep("B",3)),
  weight = c(10,11,12,20,25,30)
)

方法一:直观逐行排除(适合小数据集)

这个方法直接针对每一行,排除当前观测后计算标准差,逻辑非常清晰:

library(dplyr)
library(purrr)

df_processed <- df %>%
  group_by(country) %>%
  mutate(standarddeviation = map_dbl(row_number(), ~sd(weight[-.]))) %>%
  ungroup()

代码解释:

  • group_by(country):先按国家分组,确保我们只在同一个国家的范围内计算
  • map_dbl(row_number(), ~sd(weight[-.])):对组内每一行的行号,执行「去掉当前行的weight,计算标准差」的操作,map_dbl保证返回的是数值型向量,刚好能作为新列添加
  • ungroup():最后取消分组,回到普通数据框格式

运行后你会得到完全符合预期的结果:

# A tibble: 6 × 3
  country weight standarddeviation
  <chr>    <dbl>             <dbl>
1 A           10             0.707
2 A           11             1    
3 A           12             0.707
4 B           20             3.54 
5 B           25             7.07 
6 B           30             3.54 

方法二:数学公式推导(适合大数据集)

如果你的数据集很大,逐行操作效率会偏低,这时候可以用方差的数学公式来推导,全程向量化操作,速度快很多:

df_processed <- df %>%
  group_by(country) %>%
  mutate(
    n = n(),
    sum_w = sum(weight),
    sum_w2 = sum(weight^2),
    # 计算排除当前值的方差
    var_excl = (sum_w2 - weight^2 - (sum_w - weight)^2/(n-1))/(n-2),
    # 开根号得到标准差
    standarddeviation = sqrt(var_excl)
  ) %>%
  # 去掉中间计算的辅助列
  select(-n, -sum_w, -sum_w2, -var_excl) %>%
  ungroup()

原理说明:

我们利用方差的计算公式:样本方差 = $\frac{\sum x^2 - \frac{(\sum x)^2}{n}}{n-1}$。当排除当前观测值$x_i$后,新的总和是$\sum x - x_i$,新的平方和是$\sum x^2 - x_i^2$,新的样本量是$n-1$,代入公式就能得到排除当前值的方差,再开根号就是标准差啦。

这个方法和第一种方法结果完全一致,但速度会快很多,适合处理十万行以上的大数据集。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:37:18