【问题标题】:Group a data.table using a column which is list使用列表列对 data.table 进行分组
【发布时间】:2016-07-31 15:16:28
【问题描述】:

我有一个非常大的问题,循环遍历 data.table 来做我想做的事情太慢了,所以我试图绕过循环。假设我有一个 data.table 如下:

a <- data.table(i = c(1,2,3), j = c(2,2,6), k = list(c("a","b"),c("a","c"),c("b")))

> a
  i j   k
1: 1 2 a,b
2: 2 2 a,c
3: 3 6   b

我想根据 k 中的值进行分组。所以是这样的:

a[, sum(j), by = k]

现在我收到以下错误:

 Error in `[.data.table`(a, , sum(i), by = k) : 
 The items in the 'by' or 'keyby' list are length (2,2,1). Each must be same length as rows in x or number of rows returned by i (3).

我正在寻找的答案是首先将 k 列中具有“a”的所有行分组并计算 sum(j),然后计算所有具有“b”的行,依此类推。所以想要的答案是:

k V1 
a 4
b 8
c 2

任何提示如何有效地做到这一点?我不能通过重复行来融化列 K,因为 data.table 的大小对于我的情况来说太大了。

【问题讨论】:

标签: r data.table


【解决方案1】:

我认为这可能有效:

a[, .(k = unlist(k)), by=.(i,j)][,sum(j),by=k]

   k V1
1: a  4
2: b  8
3: c  2

【讨论】:

    【解决方案2】:

    如果我们使用tidyr,一个紧凑的选项将是

    library(tidyr)
    unnest(a, k)[, sum(j) ,k]
    #   k V1
    #1: a  4
    #2: b  8
    #3: c  2
    

    或使用dplyr/tidyr 管道

    unnest(a, k) %>%
           group_by(k) %>%
           summarise(V1 = sum(j))
    #     k    V1
    #   <chr> <dbl>
    #1     a     4
    #2     b     8
    #3     c     2
    

    【讨论】:

      【解决方案3】:

      由于按组操作可能很慢,我会考虑...

      dat = a[rep(1:.N, lengths(k)), c(.SD, .(k = unlist(a$k))), .SDcols=setdiff(names(a), "k")]
      
         i j k
      1: 1 2 a
      2: 1 2 b
      3: 2 2 a
      4: 2 2 c
      5: 3 6 b
      

      我们重复行列 i:j 以匹配未列出的 k。数据应该以这种格式保存,而不是使用列表列,可能。从那里,就像@MikeyMike 的回答一样,我们可以dat[, sum(j), by=k]

      在 data.table 1.9.7+ 中,我们可以类似地做

      dat = a[, c(.SD[rep(.I, lengths(k))], .(k = unlist(k))), .SDcols=i:j]
      

      【讨论】:

      • 单独回答,因为我并不乐观地认为其他回答者会注意到评论并进行了编辑。
      • 我没有关注你在这里所做的事情,当我尝试运行时它会抛出错误,你知道这是为什么吗?长度错误(k):找不到对象“k”
      • @newbie 是的,我想我没有看到那个错误只是因为我在包的开发版本上(我们可以在 j 中引用 .SD 之外的列)。我将编辑以注意这种不兼容性并展示另一种方式。我在这里所做的与您在 akrun 的答案中的 unnest 或 MikeyMike 中的 unlist 后看到的相同,但可能更有效,因为逐行操作(如 Mike 的答案)可能很慢。
      猜你喜欢
      • 2012-09-10
      • 2018-07-10
      • 1970-01-01
      • 2013-09-05
      • 1970-01-01
      • 1970-01-01
      • 2015-04-07
      • 2015-12-18
      相关资源
      最近更新 更多