R 数据表:从数值中减去水平意味着

R 数据表:从数值中减去水平意味着,r,dataframe,data.table,R,Dataframe,Data.table,我想知道如何从data.table中的值中减去levels means。我的MWE如下所示 set.seed(12345) A <- rep(x=paste0("A", 1:2), each=6) B <- rep(x=paste0("B", 1:3), each=2, times=2) Rep <- rep(x=1:2, times=3) Y <- rnorm(n=12, mean = 50, sd = 5) library(data.table) dt <-

我想知道如何从
data.table
中的值中减去levels means。我的MWE如下所示

set.seed(12345)
A <- rep(x=paste0("A", 1:2), each=6)
B <- rep(x=paste0("B", 1:3), each=2, times=2)
Rep <- rep(x=1:2, times=3)
Y <- rnorm(n=12, mean = 50, sd = 5)

library(data.table)
dt <- data.table(A, B, Rep, Y)

dt[, j=mean(Y), by=.(A, B)]
dt[, j=mean(Y), by=.(A)]

dt[, j=mean(Y), by=.(A, B)] - dt[, j=mean(Y), by=.(A)]

Error in Ops.data.frame(dt[, j = mean(Y), by = .(A, B)], dt[, j = mean(Y),  : 
  ‘-’ only defined for equally-sized data frames

得到错误的原因是两个数据表的维度不同。另一方面,您可以使用
数据进行链式转换。table

dt[, j := mean(Y), .(A, B)][, j := j - mean(Y), .(A)]
dt
     A  B Rep        Y          j
 1: A1 B1   1 52.92764  3.6373822
 2: A1 B1   2 53.54733  3.6373822
 3: A1 B2   1 49.45348 -1.0071061
 4: A1 B2   2 47.73251 -1.0071061
 5: A1 B3   1 53.02944 -2.6302761
 6: A1 B3   2 40.91022 -2.6302761
 7: A2 B1   1 53.15049  0.1752053
 8: A2 B1   2 48.61908  0.1752053
 9: A2 B2   1 48.57920 -3.7182851
10: A2 B2   2 45.40339 -3.7182851
11: A2 B3   1 49.41876  3.5430798
12: A2 B3   2 59.08656  3.5430798
对于更新,您可以执行以下操作:

dt[, j := mean(Y), .(A, B)][, j := j - mean(Y), .(A)][, j := j - mean(Y), .(B)][, j := j + mean(Y)]
dt
     A  B Rep        Y         j
 1: A1 B1   1 52.92764  1.731088
 2: A1 B1   2 53.54733  1.731088
 3: A1 B2   1 49.45348  1.355590
 4: A1 B2   2 47.73251  1.355590
 5: A1 B3   1 53.02944 -3.086678
 6: A1 B3   2 40.91022 -3.086678
 7: A2 B1   1 53.15049 -1.731088
 8: A2 B1   2 48.61908 -1.731088
 9: A2 B2   1 48.57920 -1.355590
10: A2 B2   2 45.40339 -1.355590
11: A2 B3   1 49.41876  3.086678
12: A2 B3   2 59.08656  3.086678

谢谢@Psidom的回答。想知道如何做这样复杂的计算
dt[,j=mean(Y),by=(A,B)]-dt[,j=mean(Y),by=(A)]-dt[,j=mean(Y),by=(B)]+dt[,j=mean(Y)]
。同样地,谢谢你,如果你把所有的业务都联系在一起,你应该能够得到你想要的。例如
dt[,j:=mean(Y),(A,B)][,j:=j-mean(Y),(A)][,j:=j-mean(Y),(B)][,j:=j+mean(Y)]
。注意:OP使用
j
作为
[.data.table
的命名参数,但实际上您正在创建一个名为
j
的列,这是一些人(像我一样)所做的可能会觉得困惑。“弗兰克。我看到了你关心的问题。然而,一个命名为“代码”> GROPBY 的结果将导致不同的维数,这使得减法变得困难。这就是为什么我认为创建一个新的向量更直接的方式。是的,我赞成并认为这是正确的方法,我只是想找到另一个名字。,这就是我的意思。
dt[, j := mean(Y), .(A, B)][, j := j - mean(Y), .(A)][, j := j - mean(Y), .(B)][, j := j + mean(Y)]
dt
     A  B Rep        Y         j
 1: A1 B1   1 52.92764  1.731088
 2: A1 B1   2 53.54733  1.731088
 3: A1 B2   1 49.45348  1.355590
 4: A1 B2   2 47.73251  1.355590
 5: A1 B3   1 53.02944 -3.086678
 6: A1 B3   2 40.91022 -3.086678
 7: A2 B1   1 53.15049 -1.731088
 8: A2 B1   2 48.61908 -1.731088
 9: A2 B2   1 48.57920 -1.355590
10: A2 B2   2 45.40339 -1.355590
11: A2 B3   1 49.41876  3.086678
12: A2 B3   2 59.08656  3.086678