【问题标题】:How to put different size vectors in data.table column如何在 data.table 列中放置不同大小的向量
【发布时间】:2016-06-06 15:22:09
【问题描述】:

我已经使用?stats::aggregate 函数实现了一个简单的分组操作。它在向量中收集每组的元素。我想使用 data.table 包让它更快。但是我无法使用 data.table 重现想要的行为。

样本数据集:

df <- data.frame(group = c("a","a","a","b","b","b","b","c","c"), val = c("A","B","C","A","B","C","D","A","B"))

使用 data.table 重现的输出:

by_group_aggregate <- aggregate(x = df$val, by = list(df$group), FUN = c)

我尝试过的:

data_t <- data.table(df)
# working, but not what I want
by_group_datatable <- data_t[,j = paste(val,collapse=","), by = group]
# no grouping done when using c or as.vector
by_group_datatable <- data_t[,j = c(val), by = group]
by_group_datatable <- data_t[,j = as.vector(val), by = group]
# grouping leads to error when using as.list
by_group_datatable <- data_t[,j = as.list(val), by = group]

data.table 列中是否可以有不同大小的向量?如果是,我该如何实现?

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    这是一种方法:

    data_t[, list(list(val)), by = group]
    #   group      V1
    #1:     a   A,B,C
    #2:     b A,B,C,D
    #3:     c     A,B
    

    使用第一个list() 是因为您要聚合结果。使用第二个 list 是因为您希望将 val 列聚合到每个组的单独列表中。

    检查结构:

    str(data_t[, list(list(val)), by = group])
    #Classes ‘data.table’ and 'data.frame': 3 obs. of  2 variables:
    # $ group: Factor w/ 3 levels "a","b","c": 1 2 3
    # $ V1   :List of 3
    #  ..$ : Factor w/ 4 levels "A","B","C","D": 1 2 3
    #  ..$ : Factor w/ 4 levels "A","B","C","D": 1 2 3 4
    #  ..$ : Factor w/ 4 levels "A","B","C","D": 1 2
    # - attr(*, ".internal.selfref")=<externalptr> 
    

    使用 dplyr,您可以执行以下操作:

    library(dplyr)
    df %>% group_by(group) %>% summarise(val = list(val))
    #Source: local data frame [3 x 2]
    #
    #   group         val
    #  (fctr)       (chr)
    #1      a <S3:factor>
    #2      b <S3:factor>
    #3      c <S3:factor>
    

    检查结构:

    df %>% group_by(group) %>% summarise(val = list(val)) %>% str
    #Classes ‘tbl_df’, ‘tbl’ and 'data.frame':  3 obs. of  2 variables:
    # $ group: Factor w/ 3 levels "a","b","c": 1 2 3
    # $ val  :List of 3
    #  ..$ : Factor w/ 4 levels "A","B","C","D": 1 2 3
    #  ..$ : Factor w/ 4 levels "A","B","C","D": 1 2 3 4
    #  ..$ : Factor w/ 4 levels "A","B","C","D": 1 2
    

    【讨论】:

    • 为了使其(也许)更易于阅读,可以在 data.table 的情况下将外部列表切换为点:.(list(val))
    【解决方案2】:

    这是dplyr/tidyr的另一个选项

    library(dplyr)
    library(tidyr)
    res <- df %>% 
            nest(-group)
    str(res)
    #'data.frame':   3 obs. of  2 variables:
    # $ group: Factor w/ 3 levels "a","b","c": 1 2 3
    # $ data :List of 3
    #  ..$ :'data.frame':    3 obs. of  1 variable:
    #  .. ..$ val: Factor w/ 4 levels "A","B","C","D": 1 2 3
    #  ..$ :'data.frame':    4 obs. of  1 variable:
    #  .. ..$ val: Factor w/ 4 levels "A","B","C","D": 1 2 3 4
    #  ..$ :'data.frame':    2 obs. of  1 variable:
    #  .. ..$ val: Factor w/ 4 levels "A","B","C","D": 1 2
    

    【讨论】:

    • 我也想过这一点,但我们应该注意它创建了一个 data.frame 列表,而 data.table 版本创建了一个因素列表。顺便说一句,我认为如果您以 iris %&gt;% nest(-Species) 为例,打印仍然可以改进
    • @docendodiscimus 感谢您的评论。我没有得到printing 部分。
    • 我只是说运行 iris %&gt;% nest(-Species) 会创建一个不太可读的输出 (tidyr 0.4.1)
    猜你喜欢
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-14
    • 2014-07-20
    • 1970-01-01
    相关资源
    最近更新 更多