我正在使用以下代码来计算每个班级的分组平均值。我需要每个类的平均值,将其放置在每一行上,但忽略公式中每一行的值(请参见expected_mean
列)。尽管该DT方法可以计算均值,但它不会忽略每一行(请参见列value_mean
)。
## create dataset
dataset <- data.frame(matrix(ncol = 2, nrow = 6))
colnames(dataset) <- c('class','value')
dataset$class <- c(rep('A',3),rep('B',3))
dataset$value <- 1:6
## convert to DT and aggregate
setDT(dataset)
dataset[, value_mean := mean(value), by=class]
## expected means (without itself)
dataset$expected_means <- c(2.5,2,1.5,5.5,5,4.5)
这将返回:
class value value_mean expected_means
A 1 2 2.5
A 2 2 2.0
A 3 2 1.5
B 4 5 5.5
B 5 5 5.0
B 6 5 4.5
我需要计算每个类的平均值,将其放置在每行中,但是要忽略当前值。例如,对于第一行,它应该只执行(1+2+3)/3
(2+3)/2
答案 0 :(得分:3)
肯定有一种比sapply
更有效的方法,但是您可以这样做:
setDT(dataset)[, value_mean := sapply(1:.N, function(x) mean(value[-x])), by = class]
输出:
class value expected_means value_mean
1: A 1 2.5 2.5
2: A 2 2.0 2.0
3: A 3 1.5 1.5
4: B 4 5.5 5.5
5: B 5 5.0 5.0
6: B 6 4.5 4.5
答案 1 :(得分:2)
这是另一种选择:
dataset[, expected_means := (sum(value) - value) / (.N - 1L), class]
答案 2 :(得分:1)
您可以使用sqldf
:
library(sqldf)
dataset <- data.frame(class = rep(c("A", "B"), each = 3),
value = 1:6,
stringsAsFactors = FALSE)
result = sqldf('select d.*,
t.sum * 1.0 / (t.count * 1.0) as value_mean,
(t.sum - d.value)*1.0/ ((t.count - 1) * 1.0) as expected_means
from dataset as d JOIN
(select class, sum(value) as sum, count(*) as count
from dataset
group by class) as t
on d.class = t.class')