在 R 中按组留一法
Leave-one out means by group in R
想象一下 table 随着时间的推移,不同公司的个人。我试图为每个人计算他们同事的平均工资(即他们公司在时间 t 的平均工资,不包括他们)。我有一个在 R 中使用 data.table 的工作代码,但我想知道是否有更好、更有效的方法:
foo <- data.table(
i = rep(1:6, each = 2),
t = rep(1:2, 6),
f = rep(1:2, each = 6),
w = 1:12
)
foo[, x := mean(foo[t == .BY$t & f == foo[i == .BY$i & t == .BY$t]$f & i != .BY$i]$w), by = .(i, t)]
我不知道这是否更容易阅读,但这是 pmap
:
的一种方法
library(dplyr); library(purrr)
foo %>%
mutate(x = pmap_dbl(cur_data(),~ cur_data() %>%
filter(i != ..1, t == ..2, f == ..3) %>%
pull(w) %>%
mean))
# i t f w x
# 1: 1 1 1 1 4
# 2: 1 2 1 2 5
# 3: 2 1 1 3 3
# 4: 2 2 1 4 4
# 5: 3 1 1 5 2
# 6: 3 2 1 6 3
# 7: 4 1 2 7 10
# 8: 4 2 2 8 11
# 9: 5 1 2 9 9
#10: 5 2 2 10 10
#11: 6 1 2 11 8
#12: 6 2 2 12 9
我们可以直接计算LOO均值:将所有工资相加,减去当前行工资,除以行数减1。
foo[, loow := (sum(w) - w) / (.N - 1), by = .(f, t)]
# i t f w x loow
# 1: 1 1 1 1 4 4
# 2: 1 2 1 2 5 5
# 3: 2 1 1 3 3 3
# 4: 2 2 1 4 4 4
# 5: 3 1 1 5 2 2
# 6: 3 2 1 6 3 3
# 7: 4 1 2 7 10 10
# 8: 4 2 2 8 11 11
# 9: 5 1 2 9 9 9
# 10: 5 2 2 10 10 10
# 11: 6 1 2 11 8 8
# 12: 6 2 2 12 9 9
也许是这样:
foo[, V1 := sapply(i, function(x) mean(w[-match(x,i)])) , by=.(f, t)]
# i t f w V1
# 1: 1 1 1 1 4
# 2: 1 2 1 2 5
# 3: 2 1 1 3 3
# 4: 2 2 1 4 4
# 5: 3 1 1 5 2
# 6: 3 2 1 6 3
# 7: 4 1 2 7 10
# 8: 4 2 2 8 11
# 9: 5 1 2 9 9
# 10: 5 2 2 10 10
# 11: 6 1 2 11 8
# 12: 6 2 2 12 9
想象一下 table 随着时间的推移,不同公司的个人。我试图为每个人计算他们同事的平均工资(即他们公司在时间 t 的平均工资,不包括他们)。我有一个在 R 中使用 data.table 的工作代码,但我想知道是否有更好、更有效的方法:
foo <- data.table(
i = rep(1:6, each = 2),
t = rep(1:2, 6),
f = rep(1:2, each = 6),
w = 1:12
)
foo[, x := mean(foo[t == .BY$t & f == foo[i == .BY$i & t == .BY$t]$f & i != .BY$i]$w), by = .(i, t)]
我不知道这是否更容易阅读,但这是 pmap
:
library(dplyr); library(purrr)
foo %>%
mutate(x = pmap_dbl(cur_data(),~ cur_data() %>%
filter(i != ..1, t == ..2, f == ..3) %>%
pull(w) %>%
mean))
# i t f w x
# 1: 1 1 1 1 4
# 2: 1 2 1 2 5
# 3: 2 1 1 3 3
# 4: 2 2 1 4 4
# 5: 3 1 1 5 2
# 6: 3 2 1 6 3
# 7: 4 1 2 7 10
# 8: 4 2 2 8 11
# 9: 5 1 2 9 9
#10: 5 2 2 10 10
#11: 6 1 2 11 8
#12: 6 2 2 12 9
我们可以直接计算LOO均值:将所有工资相加,减去当前行工资,除以行数减1。
foo[, loow := (sum(w) - w) / (.N - 1), by = .(f, t)]
# i t f w x loow
# 1: 1 1 1 1 4 4
# 2: 1 2 1 2 5 5
# 3: 2 1 1 3 3 3
# 4: 2 2 1 4 4 4
# 5: 3 1 1 5 2 2
# 6: 3 2 1 6 3 3
# 7: 4 1 2 7 10 10
# 8: 4 2 2 8 11 11
# 9: 5 1 2 9 9 9
# 10: 5 2 2 10 10 10
# 11: 6 1 2 11 8 8
# 12: 6 2 2 12 9 9
也许是这样:
foo[, V1 := sapply(i, function(x) mean(w[-match(x,i)])) , by=.(f, t)]
# i t f w V1
# 1: 1 1 1 1 4
# 2: 1 2 1 2 5
# 3: 2 1 1 3 3
# 4: 2 2 1 4 4
# 5: 3 1 1 5 2
# 6: 3 2 1 6 3
# 7: 4 1 2 7 10
# 8: 4 2 2 8 11
# 9: 5 1 2 9 9
# 10: 5 2 2 10 10
# 11: 6 1 2 11 8
# 12: 6 2 2 12 9