7

我有一个 data.table,它有两个键:Year(10 个级别)和 MemberID(200,000 个级别)。当我设置键时,会setkey(MemberID, Year)产生不同的性能setkey(Year, MemberID)吗?如果是这样,哪种方式会更好?

4

1 回答 1

8

键设置的性能和速度将取决于键变量类型。numeric列将比integer. character列(短字符串时)似乎很快。

例如

 library(data.table)

set.seed(1)
 DIC <- data.table(year = sample(seq_len(10), 5e6, TRUE), id = sample(as.character(seq_len(2e5)), 5e6, TRUE), z = rnorm(5e6))
DIC2 <- copy(DIC)
DIF <-  data.table(year = sample(seq_len(10), 5e6, TRUE), id = sample(as.factor(seq_len(2e5)), 5e6, TRUE), z = rnorm(5e6))
DIF2 <- copy(DIF)
DNC <- data.table(year = sample(as.numeric(seq_len(10)), 5e6, TRUE), id = sample(as.character(seq_len(2e5)), 5e6, TRUE), z = rnorm(5e6))
DNC2 <- copy(DNC)
DCC <- data.table(year = sample(as.character(seq_len(10)), 5e6, TRUE), id = sample(as.character(seq_len(2e5)), 5e6, TRUE), z = rnorm(5e6))
DCC2 <- copy(DCC)
 DII <- data.table(year = sample(seq_len(10), 5e6, TRUE), id = sample(seq_len(2e5), 5e6, TRUE), z = rnorm(5e6))
DII2 <- copy(DII)

一些时间

# key of integer, character columns
system.time(setkey(DIC, year ,id))
   user  system elapsed 
   3.21    0.11    3.31 
system.time(setkey(DIC2, id, year))
   user  system elapsed 
   3.43    0.03    3.45 
# key of integer factor columns
system.time(setkey(DIF, year ,id))
   user  system elapsed 
   6.31    0.05    6.37 
system.time(setkey(DIF2, id, year))
   user  system elapsed 
   6.44    0.06    6.54 
# key of numeric, character columns
system.time(setkey(DNC, year ,id))
   user  system elapsed 
   9.91    0.07   10.29 
system.time(setkey(DNC2, id, year))
   user  system elapsed 
  10.11    0.07   10.34 
# key of two character columns
system.time(setkey(DCC, year ,id))
   user  system elapsed 
   3.34    0.05    3.40 
system.time(setkey(DCC2, id, year))
   user  system elapsed 
   3.40    0.02    3.42 
# key of two integer columns
system.time(setkey(DII, year ,id))
   user  system elapsed 
   6.25    0.02    6.53 
system.time(setkey(DII2, id,year))
   user  system elapsed 
   6.44    0.05    6.64 

至于哪种方式会更好。这可能取决于您最有可能更频繁地单独进行子集化的内容。

例如,您可能需要获取第 1 年的所有数据。

如果您已将密钥设置为,year, id则可以使用

D[J(1)]

但如果密钥设置为id, year那么你需要

D[J(unique(id),1), nomatch = 0]

这是更多的打字,并且需要更长的时间,因为它必须计算unique(id)

有一个功能请求FR#1007着眼于允许辅助键,但这还没有实现。目前有一个键可以占用多列。

于 2012-12-04T01:22:43.143 回答