繁体   English   中英

使用 dplyr 在排除当前观察的同时计算组平均值

[英]Calculate group mean while excluding current observation using dplyr

使用dplyr (最好),我试图计算每个观察的组平均值,同时从组中排除该观察。

似乎这应该可以通过rowwise()group_by()的组合来rowwise() ,但是这两个函数不能同时使用。

鉴于此数据框:

df <- data_frame(grouping = rep(LETTERS[1:5], 3),
                 value = 1:15) %>%
  arrange(grouping)
df
#> Source: local data frame [15 x 2]
#> 
#>    grouping value
#>       (chr) (int)
#> 1         A     1
#> 2         A     6
#> 3         A    11
#> 4         B     2
#> 5         B     7
#> 6         B    12
#> 7         C     3
#> 8         C     8
#> 9         C    13
#> 10        D     4
#> 11        D     9
#> 12        D    14
#> 13        E     5
#> 14        E    10
#> 15        E    15

我想获得每个观察的组均值,该观察被排除在组之外,导致:

#>    grouping value special_mean
#>       (chr) (int)
#> 1         A     1          8.5  # i.e. (6 + 11) / 2
#> 2         A     6            6  # i.e. (1 + 11) / 2
#> 3         A    11          3.5  # i.e. (1 + 6) / 2
#> 4         B     2          9.5
#> 5         B     7            7
#> 6         B    12          4.5
#> 7         C     3          ...

我尝试将rowwise()嵌套在由do()调用的函数中,但没有让它工作,如下所示:

special_avg <- function(chunk) {
  chunk %>%
    rowwise() #%>%
    # filter or something...?
}

df %>%
  group_by(grouping) %>%
  do(special_avg(.))

无需定义自定义函数,而是简单地对该组的所有元素求和,减去当前值,并除以每组元素数减1

df %>% group_by(grouping) %>%
        mutate(special_mean = (sum(value) - value)/(n()-1))
#   grouping value special_mean
#      (chr) (int)        (dbl)
#1         A     1          8.5
#2         A     6          6.0
#3         A    11          3.5
#4         B     2          9.5
#5         B     7          7.0

我偶然遇到了这个老问题,我想知道是否有一个通用的解决方案也适用于除mean()之外的其他聚合函数,例如jlesuffleurmedium max()要求的 max median()

这个想法是通过循环实际组中的行来从计算聚合中省略实际行:

library(dplyr)
df %>% 
  group_by(grouping) %>% 
  mutate(special_mean = sapply(1:n(), function(i) mean(value[-i])))
 grouping value special_mean <chr> <int> <dbl> 1 A 1 8.5 2 A 6 6 3 A 11 3.5 4 B 2 9.5 5 B 7 7 ...

这也适用于max()

df %>% 
  group_by(grouping) %>% 
  mutate(special_max = sapply(1:n(), \(i) max(value[-i])))
 grouping value special_max <chr> <int> <int> 1 A 1 11 2 A 6 11 3 A 11 6 4 B 2 12 5 B 7 12 6 B 12 7 ...

为了完整起见,这里还有一个解决方案:

library(data.table)
setDT(df)[, special_mean := sapply(1:.N, function(i) mean(value[-i])), by = grouping][]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM