将 .GRP 应用于 data.table R 中的多列以分别对每一列进行分组
apply .GRP to multiple columns in data.table R to group each column separately
我有一个很大的 data.table(2 亿行 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 解决方案。
一种方法是使用 match
和 unique
:
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
我有一个很大的 data.table(2 亿行 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 解决方案。
一种方法是使用 match
和 unique
:
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