设置相同的键但顺序不同时加入

问题描述 投票:0回答:1

我不明白为什么连接数据表中键的顺序会产生影响。

考虑将

tmp_dt_1
连接到
tmp_dt_2
的以下(预期)结果:

tmp_dt_1 <- 
    data.table(a = c(1, 2), b = c(2, 1), c = 1:2)

tmp_dt_2 <- 
    data.table(a = c(1, 2), b = c(2, 1), d = 1:2)


setkeyv(tmp_dt_1, c("a", "b"))


setkeyv(tmp_dt_2, c("a", "b"))


tmp_dt_1

# Key: <a, b>
#     a     b     c
#     <num> <num> <int>
# 1:     1     2     1
# 2:     2     1     2


tmp_dt_2

# Key: <a, b>
#     a     b     d
#     <num> <num> <int>
# 1:     1     2     1
# 2:     2     1     2


tmp_dt_1[tmp_dt_2]
# Key: <a, b>
#     a     b     c     d
#     <num> <num> <int> <int>
# 1:     1     2     1     1
# 2:     2     1     2     2

现在,按

tmp_dt_2
b
,然后按
a
。与上面的连接相比,这会产生不同(并且错误)的连接:

setkeyv(tmp_dt_2, c("b", "a"))

tmp_dt_1
# Key: <a, b>
#     a     b     c
#   <num> <num> <int>
# 1:     1     2     1
# 2:     2     1     2


tmp_dt_2

# Key: <b, a>
#     a     b     d
#   <num> <num> <int>
# 1:     2     1     2
# 2:     1     2     1



tmp_dt_1[tmp_dt_2]

# Key: <a, b>
#     a     b     c     d
#     <num> <num> <int> <int>
# 1:     1     2     1     2
# 2:     2     1     2     1
r join data.table
1个回答
0
投票

data.table 中的主索引和辅助索引是什么? 中,

data.table
文档说:

setkey(DT, col1, col2)
按列
col1
对行进行排序,然后在每组
col1
中按
col2
进行排序。这是一个主要索引。行顺序通过 RAM 中的引用进行更改...我们可以互换使用索引和键这两个词。

强调我的

这些键决定 RAM 中的行顺序,如果

data.table
可以利用此顺序,则可以进行低级优化。 例如,它可以最大限度地减少页面获取并批量复制内存而不是循环。

这意味着顺序很重要。因此,当您按照第二种情况中的顺序指定键时,您实际上是在执行以下操作:

tmp_dt_1[
    tmp_dt_2,
    on = .(a = b, b = a)
]

如果我们只设置一个键,我们可以更清楚地看到这一点:

all(
    tmp_dt_1[tmp_dt_2] == 
        tmp_dt_1[tmp_dt_2, on = .(a)]
) # FALSE

all(
    tmp_dt_1[tmp_dt_2] == 
        tmp_dt_1[tmp_dt_2, on = .(a = b)]
) # TRUE

如果您担心这一点,最简单的方法是使用两个

data.table
相同的向量来设置键,例如

keys <- c("a", "b")
setkeyv(tmp_dt_1, keys)
setkeyv(tmp_dt_2, keys)
© www.soinside.com 2019 - 2024. All rights reserved.