data.table中键的顺序是否重要?

时间:2012-12-04 00:49:57

标签: r data.table

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

1 个答案:

答案 0 :(得分: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,它考虑允许使用辅助密钥,但尚未实现。目前,只有一个密钥可以占用多个列。