计算分组均值而忽略每一行值

时间:2020-04-20 15:34:54

标签: r mean

我正在使用以下代码来计算每个班级的分组平均值。我需要每个类的平均值,将其放置在每一行上,但忽略公式中每一行的值(请参见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

3 个答案:

答案 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')