gpt4 book ai didi

r - 使用 data.table 按变量分组查找均值差

转载 作者:行者123 更新时间:2023-12-04 03:20:02 25 4
gpt4 key购买 nike

假设,我有以下data.table

library(data.table)
dt <- data.table(x1 = c(1:12), x2=c(21:32))

然后,我使用以下方法按用户指定的时间间隔创建 bin:

dt[,intx1:=cut(x1, breaks = c(-Inf, 4, 9, Inf))]

返回,

    x1 x2    intx1
1: 1 21 (-Inf,4]
2: 2 22 (-Inf,4]
3: 3 23 (-Inf,4]
4: 4 24 (-Inf,4]
5: 5 25 (4,9]
6: 6 26 (4,9]
7: 7 27 (4,9]
8: 8 28 (4,9]
9: 9 29 (4,9]
10: 10 30 (9, Inf]
11: 11 31 (9, Inf]
12: 12 32 (9, Inf]

我正在尝试找出 bin 和变量之间的平均差异:

dt[, mux1_grp:=mean(x1), by = intx1][,mux1_pop:=mean(x1)][,mux1_diff:=mux1_grp-mux1_pop]
dt[,`:=`(intx1=NULL, mux1_grp=NULL, mux1_pop=NULL)]

返回是:

    x1 x2 mux1_diff
1: 1 21 -4.0
2: 2 22 -4.0
3: 3 23 -4.0
4: 4 24 -4.0
5: 5 25 0.5
6: 6 26 0.5
7: 7 27 0.5
8: 8 28 0.5
9: 9 29 0.5
10: 10 30 4.5
11: 11 31 4.5
12: 12 32 4.5

但是,我的原始数据包含多个变量(例如 x1、x2、...、x20)。
因此,我必须对 x2 重复相同的过程,如下所示:

dt[,intx2:=cut(x2, breaks = c(-Inf, 25, 28, Inf))]
dt[, mux2_grp:=mean(x2), by = intx2][,mux2_pop:=mean(x2)][,mux2_diff:=mux2_grp-mux2_pop]
dt[,`:=`(intx2=NULL, mux2_grp=NULL, mux2_pop=NULL)]

我的最终输出将是:

    x1 x2 mux1_diff mux2_diff
1: 1 21 -4.0 -3.5
2: 2 22 -4.0 -3.5
3: 3 23 -4.0 -3.5
4: 4 24 -4.0 -3.5
5: 5 25 0.5 -3.5
6: 6 26 0.5 0.5
7: 7 27 0.5 0.5
8: 8 28 0.5 0.5
9: 9 29 0.5 4.0
10: 10 30 4.5 4.0
11: 11 31 4.5 4.0
12: 12 32 4.5 4.0

我该如何改进这段代码?请注意,每个变量都有不同的用户指定区间

最佳答案

我们可以在紧凑的一步选项中完成此操作(尽管与 OP 的方法(来自@Frank 的评论)相比,它可能不是最佳选择

dt[, mu_diff := mean(x) - mean(dt$x), by = .(cut(x, breaks = c(-Inf, 4, 9, Inf)))][]
# x mu_diff
#1: 1 -3.8636364
#2: 2 -3.8636364
#3: 3 -3.8636364
#4: 4 -3.8636364
#5: 5 0.3863636
#6: 6 0.3863636
#7: 7 0.3863636
#8: 9 0.3863636
#9: 10 4.6363636
#10:11 4.6363636
#11:12 4.6363636

如果有很多变量(不清楚我们是否在 cut 中使用相同的 breaks 或不同的列 - 假设它是相同的),我们可以遍历列(在下面的可重现示例中,显示了两个变量“x1”和“x2”),通过列的数字索引指定 .SDcols,按 分组cut 子集列,我们将新列指定为组内值的平均值与整个列的平均值之间的差值。

nm1 <- paste0("mu_diff", seq_along(dt1))
for(j in seq_along(dt1)){
dt1[, (nm1[j]) := mean(.SD[[1L]]) - mean(dt1[[names(dt1)[j]]]),
by = .(cut(get(names(dt1)[j]), breaks = c(-Inf, 4, 9, Inf))) ,
.SDcols = j][]
}

更新 - 假设如果 cut 变量的 breaks 对于每一列不同,将它放在list 并通过索引获取 for 循环中的 list 元素。

brkLst <- list(c(-Inf, 4, 9, Inf), c(-Inf, 10, 14, Inf))
for(j in seq_along(dt1)){
dt1[, (nm1[j]) := mean(.SD[[1L]]) - mean(dt1[[names(dt1)[j]]]),
by = .(cut(get(names(dt1)[j]), breaks = brkLst[[j]])) ,
.SDcols = j][]
}

使用 OP 的新数据 ('dt2') 检查输出

brkLst2 <- list(c(-Inf, 4, 9, Inf),  c(-Inf, 25, 28, Inf))
nm1 <- paste0("mu", names(dt2), "_diff")
for(j in seq_along(dt2)){
dt2[, (nm1[j]) := mean(.SD[[1L]]) - mean(dt2[[names(dt2)[j]]]),
by = .(cut(get(names(dt2)[j]), breaks = brkLst2[[j]])) ,
.SDcols = j][]
}

dt2
# x1 x2 mux1_diff mux2_diff
# 1: 1 21 -4.0 -3.5
# 2: 2 22 -4.0 -3.5
# 3: 3 23 -4.0 -3.5
# 4: 4 24 -4.0 -3.5
# 5: 5 25 0.5 -3.5
# 6: 6 26 0.5 0.5
# 7: 7 27 0.5 0.5
# 8: 8 28 0.5 0.5
# 9: 9 29 0.5 4.0
#10: 10 30 4.5 4.0
#11: 11 31 4.5 4.0
#12: 12 32 4.5 4.0

数据

dt1 <- data.table(x1 = c(1,2,3,4,5,6,7,9,10,11,12))[, x2 := x1 + 5][]
#OP's changed dataset
dt2 <- data.table(x1 = 1:12, x2=21:32)

关于r - 使用 data.table 按变量分组查找均值差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38886450/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com