2016-09-28 74 views
2

是否可以使用data.table来通过多个组变量来标准化一些变量?使用data.table按组进行标准化

DT <- data.table(V1=1:20, V2=40:21, gr=c(rep(c('a'),10), rep(c('b'),10)), 
      grr=rep(c(rep(c('a'),5), rep(c('b'),5)),2)) 

gr和grr是组变量。我想添加到data.table V1.z和V2.z中,这是每个gr-by-grr组中的标准化分数。

以下是一个极其愚蠢的代码,解释一下我想:

DTaa <- DT[gr=='a' & grr=='a',] 
DTab <- DT[gr=='a' & grr=='b',] 
DTba <- DT[gr=='b' & grr=='a',] 
DTbb <- DT[gr=='b' & grr=='b',] 
DTaa <- DTaa[,V1.z := scale(V1)] 
DTaa <- DTaa[,V2.z := scale(V2)] 
DTab <- DTab[,V1.z := scale(V1)] 
DTab <- DTab[,V2.z := scale(V2)] 
DTba <- DTba[,V1.z := scale(V1)] 
DTba <- DTba[,V2.z := scale(V2)] 
DTbb <- DTbb[,V1.z := scale(V1)] 
DTbb <- DTbb[,V2.z := scale(V2)] 
DTn <- rbind(DTaa, DTab, DTba, DTbb) 

也许,有一种方法中的一个或两行使用by做到这一点。

  • 我希望然后在接受数据的功能使用它,所述目标变量(在本例中,V1和V2),和基团的变量(在本例中,GR和GRR)作为参数。
  • 如果你有一个不使用data.table的解决方案,它也是很好的(我尝试了使用dplyr中的mutate_at,但是找不到关于该函数的很多文档)。

回答

3

通过“克”和“GRR”,遍历Data.table的子集(.SD),scale它(的scale输出是matrix,所以我们把它转换为vectoras.vector)和分组后将输出分配给(:=)新列。

DT[, paste0(names(DT)[1:2], ".z") := lapply(.SD, 
        function(x) as.vector(scale(x))), .(gr, grr)] 
+0

@YBA很高兴它适合你。请阅读指导[这里](http://stackoverflow.com/help/someone-answers) – akrun

+0

惊人的。谢谢。 后续问题: 我将V3和V4添加到data.table,您的代码仍然知道只转换前两个变量。这很好,但它是如何工作的?我的意思是,data.table如何知道我们只想在第一列和第二列上执行操作?我在这里看到的唯一的东西是在paste0中,但这只是新变量的名称。如果我想要使用第1列和第2列的名称并在第3列和第4列上执行操作(如果我有这些列),该怎么办? – YBA

+0

@YBA通常,'.SD'包含'by'列中没有指定的所有列,即'(gr,grr)'。假设你有一些其他的列,你只需要在'V1'和'V2'上进行操作,在'.SDcols'中指定,例如'.SDcols = V1:V2',然后循环显示'.SD'该职位。 – akrun