【问题标题】:Calculate grouped means ignoring each row value计算分组意味着忽略每一行的值
【发布时间】:2020-08-03 04:19:24
【问题描述】:

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

【问题讨论】:

    标签: r mean


    【解决方案1】:

    肯定有比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
    

    【讨论】:

      【解决方案2】:

      这是另一种选择:

      dataset[, expected_means := (sum(value) - value) / (.N - 1L), class]
      

      【讨论】:

        【解决方案3】:

        你可以使用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')
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多