代码之家  ›  专栏  ›  技术社区  ›  JdeMello

按同一列聚合列

  •  1
  • JdeMello  · 技术社区  · 6 年前

    为什么传统的列聚合语法 data.table dt[, sum(x), by = "y"] 如果我们在 j by ,即 dt[, sum(x), by = "x"] ?

    library(data.table)
    
    set.seed(1)
    dt <- data.table(x = sample(c(1:10), 20, T), y = sample(letters[1:4], 20, T))
    setorderv(dt, "y")
    

    我想和 x 通过 X 但以下内容不起作用,它只是复制了 X 专栏:

    > dt[, sum(x, na.rm = T), by = "x"]
         x V1
     1:  4  4
     2: 10 10
     3:  3  3
     4:  9  9
     5:  7  7
     6:  1  1
     7:  8  8
     8:  6  6
     9:  2  2
    10:  5  5
    

    如果我这样做:

    > dt[, .(res = lapply(.SD, sum, na.rm = T)), by = 'x', .SDcols = "x"] 
         x res
     1:  4  12
     2: 10  30
     3:  3   9
     4:  9   9
     5:  7  21
     6:  1   1
     7:  8  24
     8:  6   6
     9:  2   2
    10:  5   5
    

    那是有效的。

    另一方面,如果 通过 参数是一个不同于用于聚合的列 J :

    > dt[, sum(x, na.rm = T), by = "y"]
       y V1
    1: a 38
    2: b 38
    3: c 17
    4: d 26
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Frank    6 年前

    每列 by= 减少到一个长度,而不是将值重复到组的长度, .N ,占用更多内存。你仍然可以用乘来计算和 n 虽然:

    dt[, x*.N, by=x]
    

    …或者可以将全长向量添加到 .SD (尽管这不应该是必要的):

    dt[, sum(.SD$x), by=x, .SDcols="x"]
    

    SD 是给定数据的“子集” 被= 组。见 ?.SD ?.N 详情。