按组平均,删除当前行
average by group, removing current row
我想计算一个变量的组均值但不包括焦点受访者:
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]
有什么想法吗?
如果我没有理解错的话,我认为这是可行的:
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 复制整个组数据,并标记我们要从均值中排除的行。第二步是排除行,然后按 group/id 分组。显然这不是超级内存效率,但只要你没有内存限制就应该可以工作。
您可以试试这个解决方案:
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
看来您已经完成大部分工作了,只需要考虑 NA
的:
dat[, avg := (sum(y, na.rm=T) - ifelse(is.na(y), 0, y)) / (sum(!is.na(y)) + is.na(y) - 1)
, by = grp]
无需双循环或额外内存。
我想计算一个变量的组均值但不包括焦点受访者:
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]
有什么想法吗?
如果我没有理解错的话,我认为这是可行的:
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 复制整个组数据,并标记我们要从均值中排除的行。第二步是排除行,然后按 group/id 分组。显然这不是超级内存效率,但只要你没有内存限制就应该可以工作。
您可以试试这个解决方案:
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
看来您已经完成大部分工作了,只需要考虑 NA
的:
dat[, avg := (sum(y, na.rm=T) - ifelse(is.na(y), 0, y)) / (sum(!is.na(y)) + is.na(y) - 1)
, by = grp]
无需双循环或额外内存。