【问题标题】:Standardize by group using data.table使用 data.table 按组标准化
【发布时间】:2016-09-28 05:18:13
【问题描述】:

是否可以使用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 是组变量。我想将每个 gr-by-grr 组内的标准化分数添加到 data.table V1.z 和 V2.z 中。

这是一个非常愚蠢的代码,用来解释我想要什么:

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,但找不到太多关于该函数的文档)。

【问题讨论】:

    标签: r data.table dplyr


    【解决方案1】:

    按'gr'和'grr'分组后,循环遍历Data.table的子集(.SD),scale it(scale的输出是matrix,所以我们将其转换为vectoras.vector) 并将输出分配 (:=) 到新列。

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

    【讨论】:

    • 太棒了。谢谢。一个后续问题:我将 V3 和 V4 添加到 data.table 中,您的代码仍然知道只转换前两个变量。这很好,但它是如何工作的?我的意思是,data.table 如何知道我们希望仅在第一列和第二列上执行操作?我在这里看到的唯一内容是在 paste0 中,但这只是新变量的名称。如果我想使用第 1 列和第 2 列中的名称并对第 3 列和第 4 列执行操作(如果我有这些列)怎么办?
    • @YBA 通常,.SD 包括在by 列中未指定的所有列,即(gr, grr)。假设您有一些其他列,并且只想在“V1”和“V2”上执行,请在 .SDcols 中指定这些列,即 .SDcols = V1:V2,然后循环访问 .SD,如帖子所示。
    • .SDcols 非常有用,谢谢。所以,我知道为什么您的代码在添加 V3 和 V4 后仍然有效:似乎如果您只为新列指定两个名称,则该函数将仅在前两列上执行(不在 'by ' 声明)。
    • @YBA 可以,需要在.SDcols中指定
    猜你喜欢
    • 2020-07-02
    • 1970-01-01
    • 2015-01-13
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多