【问题标题】:apply .GRP to multiple columns in data.table R to group each column separately [duplicate]将 .GRP 应用于 data.table R 中的多个列以分别对每一列进行分组[重复]
【发布时间】:2020-12-14 22:30:36
【问题描述】:

我有一个大型 data.table(200M 行 x 300 列)DT,其中包含多个(超过 50 个)标识符列。 标识符都采用不同的格式,其中一些相当复杂和长,我想将它们(selected_cols)全部转换为简单的数字标识符。

我可以一次将 .GRP 用于一列,而且速度非常快(嗯,相对而言,在上下文中!)

DT[, new_col_1 := .GRP , by = .(col_1)]  #this works for one column at a time

有没有办法为多个列使用 .GRP 业务? 如果我使用 lapply 定义自己的函数,我知道该怎么做,但我不能在函数中使用 .GRP。可能是一厢情愿。我也可以用 for 循环来做到这一点,但我讨厌 for 循环,它们让我毛骨悚然,因为它们没有扩大规模。 只是希望避免出于速度原因创建我自己的函数或使用 for 循环。这是一个简单的操作,但对于大型 data.table 需要很长时间。

DT[ , (paste0('new_', selected_cols)) := lapply(.SD, some_function_with_.GRP), .SDcols = selected_cols)] 

这是一个 data.table 示例,如果您需要的话:

require(data.table)
DT = data.table(col1 = c('A','B','B','D','B','A','A','B','R','T','E','E','H','T','Y','F','F','F')
               ,col2 = c('DD','GG','RR','HH','SS','AA','CC','RR','EE','DD','HH','BB','CC','AA','QQ','EE','YY','MM')
               , col3 = c('FFF1', 'HHH1', 'CCC1', 'AAA1', 'FFF1', 'RRR1', 'GGG1', 'DDD1', 'FFF1', 'JJJ1', 'VVV1', 'CCC1', 'AAA1', 'XXX1', 'GGG1', 'HHH1', 'AAA1', 'RRR1'))

这是我想要的输出:

> DT
    col1 col2 col3 new_col1 new_col2 new_col3
 1:    A   DD FFF1        1        1        1
 2:    B   GG HHH1        2        2        2
 3:    B   RR CCC1        2        3        3
 4:    D   HH AAA1        3        4        4
 5:    B   SS FFF1        2        5        1
 6:    A   AA RRR1        1        6        5
 7:    A   CC GGG1        1        7        6
 8:    B   RR DDD1        2        3        7
 9:    R   EE FFF1        4        8        1
10:    T   DD JJJ1        5        1        8
11:    E   HH VVV1        6        4        9
12:    E   BB CCC1        6        9        3
13:    H   CC AAA1        7        7        4
14:    T   AA XXX1        5        6       10
15:    Y   QQ GGG1        8       10        6
16:    F   EE HHH1        9        8        2
17:    F   YY AAA1        9       11        4
18:    F   MM RRR1        9       12        5

我正在寻找原生 data.table 解决方案。

【问题讨论】:

    标签: r data.table grouping


    【解决方案1】:

    一种方法是使用matchunique

    library(data.table)
    cols <- paste0('col', 1:3)
    
    DT[, paste0('new_', cols) := lapply(.SD, function(x) 
                match(x, unique(x))), .SDcols = cols]
    DT
    
    #    col1 col2 col3 new_col1 new_col2 new_col3
    # 1:    A   DD FFF1        1        1        1
    # 2:    B   GG HHH1        2        2        2
    # 3:    B   RR CCC1        2        3        3
    # 4:    D   HH AAA1        3        4        4
    # 5:    B   SS FFF1        2        5        1
    # 6:    A   AA RRR1        1        6        5
    # 7:    A   CC GGG1        1        7        6
    # 8:    B   RR DDD1        2        3        7
    # 9:    R   EE FFF1        4        8        1
    #10:    T   DD JJJ1        5        1        8
    #11:    E   HH VVV1        6        4        9
    #12:    E   BB CCC1        6        9        3
    #13:    H   CC AAA1        7        7        4
    #14:    T   AA XXX1        5        6       10
    #15:    Y   QQ GGG1        8       10        6
    #16:    F   EE HHH1        9        8        2
    #17:    F   YY AAA1        9       11        4
    #18:    F   MM RRR1        9       12        5
    

    【讨论】:

    • 所以,我认为实际上没有办法创建一个函数,是吗?这仍然非常有用,因为您的解决方案功能比我的要快。非常感谢!如果没有进一步改进性能的建议,我会将其标记为解决方案。
    • 在我的大型数据集上比 rleid 快。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-10
    • 2016-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    相关资源
    最近更新 更多