[英]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()
之外的其他聚合函数,例如jlesuffleur或medium 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 ...
为了完整起见,这里还有一个data.table解决方案:
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.