"循环"data.table来计算条件平均值

Cak*_*ake 11 r data.table

我想"遍历"data.table的行并计算每行的平均值.平均值应根据以下机制计算:

  1. 在第i行查找标识符ID(ID(i))
  2. 在第i行中查找T2的值(T2(i))
  3. 计算满足以下两个标准的Data1所有行中的值的平均值j:ID(j) = ID(i)T1(j) = T2(i)
  4. 在第i行的Data2列中输入计算的平均值

     DF = data.frame(ID=rep(c("a","b"),each=6), 
                 T1=rep(1:2,each=3), T2=c(1,2,3), Data1=c(1:12))
     DT = data.table(DF)
     DT[ , Data2:=NA_real_]
         ID T1 T2  Data1 Data2
    [1,]  a  1  1     1    NA
    [2,]  a  1  2     2    NA
    [3,]  a  1  3     3    NA
    [4,]  a  2  1     4    NA
    [5,]  a  2  2     5    NA
    [6,]  a  2  3     6    NA
    [7,]  b  1  1     7    NA
    [8,]  b  1  2     8    NA
    [9,]  b  1  3     9    NA
    [10,] b  2  1    10    NA
    [11,] b  2  2    11    NA
    [12,] b  2  3    12    NA
    
    Run Code Online (Sandbox Code Playgroud)

对于这个简单的例子,结果应如下所示:

      ID T1 T2  Data1 Data2
[1,]  a  1  1     1    2
[2,]  a  1  2     2    5
[3,]  a  1  3     3    NA
[4,]  a  2  1     4    2
[5,]  a  2  2     5    5
[6,]  a  2  3     6    NA
[7,]  b  1  1     7    8
[8,]  b  1  2     8    11
[9,]  b  1  3     9    NA
[10,] b  2  1    10    8
[11,] b  2  2    11    11
[12,] b  2  3    12    NA
Run Code Online (Sandbox Code Playgroud)

我认为这样做的一种方法是遍历行,但我认为这是低效的.我看过这个apply()函数,但我确定它是否可以解决我的问题.我也可以使用data.frame而不是data.table如果这会使它更有效或更容易.真实数据集包含大约100万行.

Mat*_*wle 11

经验法则是首先聚合,然后加入到那里.

agg = DT[,mean(Data1),by=list(ID,T1)]
setkey(agg,ID,T1)
DT[,Data2:={JT=J(ID,T2);agg[JT,V1][[3]]}]
      ID T1 T2 Data1 Data2
 [1,]  a  1  1     1     2
 [2,]  a  1  2     2     5
 [3,]  a  1  3     3    NA
 [4,]  a  2  1     4     2
 [5,]  a  2  2     5     5
 [6,]  a  2  3     6    NA
 [7,]  b  1  1     7     8
 [8,]  b  1  2     8    11
 [9,]  b  1  3     9    NA
[10,]  b  2  1    10     8
[11,]  b  2  2    11    11
[12,]  b  2  3    12    NA
Run Code Online (Sandbox Code Playgroud)

你可以看到它在这种情况下有点难看(但会很快).计划添加drop哪个将避免这[[3]]一点,也许我们可以提供一种方法来告诉[.data.table评估i调用范围(即没有自连接),这将避免JT=这里需要的位,因为ID在两者aggDT.

keyby已经添加到R-Forge上的v1.8.0中,因此也避免了对它的需求setkey.