我有一个data.table,它有两个键:Year(10个级别)和MemberID(200,000个级别).当我使用setkey时,会setkey(MemberID, Year)
产生不同的性能setkey(Year, MemberID)
吗?如果是这样,哪种方式会更好?
键设置的性能和速度取决于键变量类型.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)
Run Code Online (Sandbox Code Playgroud)
# 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
Run Code Online (Sandbox Code Playgroud)
至于哪种方式会更好.这可能取决于您最有可能更频繁地单独分配的内容.
例如,您可能需要获取第1年的所有数据.
如果您已设置密钥,year, id
则可以使用
D[J(1)]
Run Code Online (Sandbox Code Playgroud)
但如果按键设置为id, year
那么你需要
D[J(unique(id),1), nomatch = 0]
Run Code Online (Sandbox Code Playgroud)
这是更多的打字,将需要更长的时间,因为它必须计算unique(id)
.
FR#1007有一个功能请求,它考虑允许使用辅助密钥,但这尚未实现.目前,只有一个密钥可以占用多个列.