按组平均,删除当前行

时间:2015-02-10 21:19:58

标签: r data.table

我想计算变量的组均值,但不包括焦点响应者:

set.seed(1)
dat <- data.table(id = 1:30, y = runif(30), grp = rep(1:3, each=10))

第一条记录(受访者)应该平均......第二条......依此类推:

mean(dat[c==1, y][-1])
mean(dat[c==1, y][-2])
mean(dat[c==1, y][-3])

第二组相同:

mean(dat[c==2, y][-1])
mean(dat[c==2, y][-2])
mean(dat[c==2, y][-3])

我尝试了这个,但它没有工作:

ex[, avg := mean(ex[, y][-.I]), by=grp]

有什么想法吗?

3 个答案:

答案 0 :(得分:4)

您可以尝试此解决方案:

set.seed(1)
dat <- data.table(id = 1:9, y = c(NA,runif(8)), grp = rep(1:3, each=3))

dat[, avg2 := sapply(seq_along(y),function(i) mean(y[-i],na.rm=T)), by=grp]

dat
#    id         y grp      avg2
# 1:  1        NA   1 0.3188163
# 2:  2 0.2655087   1 0.3721239
# 3:  3 0.3721239   1 0.2655087
# 4:  4 0.5728534   2 0.5549449
# 5:  5 0.9082078   2 0.3872676
# 6:  6 0.2016819   2 0.7405306
# 7:  7 0.8983897   3 0.8027365
# 8:  8 0.9446753   3 0.7795937
# 9:  9 0.6607978   3 0.9215325

答案 1 :(得分:2)

好像你大部分都在那里,只需要考虑NA

dat[, avg := (sum(y, na.rm=T) - ifelse(is.na(y), 0, y)) / (sum(!is.na(y)) + is.na(y) - 1)
    , by = grp]

不需要双循环或额外的内存。

答案 2 :(得分:1)

如果我理解正确,我认为这可以胜任:

dat[,
  .(id, y2=rep(y, .N), id2=rep(id, .N), id3=rep(id, each=.N)), by=grp      
][
  !(id2 == id3),
  mean(y2), 
  by=.(id3, grp)
]

第一步是复制每个id的整个组数据,并标记我们要从平均值中排除哪一行。第二步是排除行,然后按组/ id分组。显然这不是超级内存效率,但只要你没有内存限制就应该工作。