[英]data.table binary search fails if j refers to a numeric (extra) key column?
[英]data.table: How to do binary search for two (numeric) values at one key: example included
示例數據:
library(data.table)
DT <- data.table(a = c(1, 3, 5, 9, 15),
b = c("a", "c", "d", "e", "f"))
我想得到兩行,即a == 3 | a == 9
a == 3 | a == 9
,即
# a b
# 3 c
# 9 e
我知道是否這樣做: DT[, a:=as.character(a)]
然后setkey(DT, a)
和DT[c("3", "9")]
,我可以得到想要的結果。 但是我想知道,是否有其他方法可以在不事先將a
更改為字符的情況下進行這種二進制搜索?
首先,在執行基於聯接/二進制搜索的子集之前,不必每次都轉換為字符列。 您可以使用J()
並將整數/數字/字符/邏輯/ bit64 :: integer64矢量傳遞給它,如下所示:
DT[J(vec1, vec2, ...)]
其中, vec1
將抵靠第一鍵列和匹配vec2
靠在第二鍵列等。
不必為字符類型添加J()
的事實是一項附加功能 ,只是為了方便起見。 因為整數/數字/邏輯向量已經具有這樣的含義DT[1]
將返回第一行,所以我們無法為這些類型提供相同的快捷方式。 希望這能回答您的原始問題。
回到您的問題,使用值(3,9)
子集a
列,您可以使用data.table
基於二進制搜索的子集來實現:
require(data.table)
setkey(DT, a)
DT[J(c(3,9))] ## alternatively DT[.(c(3,9))] in 1.9.4+
# a b
# 1: 3 c
# 2: 9 e
有兩點需要注意,您可以使用data.table
的二進制搜索功能快速子集化:
為了解決這些問題並提供更好的功能,data.table在1.9.4中通過引入新的實驗功能 -在輔助鍵的幫助下自動建立索引來解決此問題。 Matt已在1.9.4中實現了這一點。
自動索引的作用是,如果尚不存在輔助鍵,則可以在data.table理解的表達式的首次運行(此刻)進行優化時,將創建輔助鍵。 它只是使用data.table的快速基數排序存儲此列的順序,並將其存儲為屬性。 與setkey
不同, setkey
沒有數據的重新排序。 您也可以使用set2key()
設置輔助密鑰。
首次運行它所花費的時間等於a)輔助鍵的時間(通常很小),以及b)查詢的時間。 從第二次開始,這只是查詢時間,使用二進制搜索可以快速進行。
如果用data.table現在可以理解的表達式查詢另一列,那么它將在該列首次運行時另外為該列設置一個輔助鍵。 等等...
兩種方法之間的速度不應有(明顯的)差異(完成setkey
和set2key
)。 請參見下面的示例。
輔助鍵的概念可以擴展到自動索引之外,也可以擴展到聯接。 這將加快data.table的連接速度。
這是一個例子。 我將使用1.9.5,因為Matt已經解決了自動索引編制中的一些錯誤。
require(data.table) ## 1.9.5+
set.seed(45L)
DT = data.table(x=sample(1e3, 5e7, TRUE))[, y := x]
setkey(DT, x)
set2key(DT, y)
請注意,在setkey(.)
DT
將通過引用重新排序。 但是set2key
只會設置一個屬性,因此不會根據y的順序對數據進行重新排序。
x和y列相同(有意)。 讓我們同時測試:
system.time(DT[J(100L)]) ## on column x, 0.003 seconds
system.time(DT[y == 100L]) ## on column y, 0.003 seconds, uses secondary keys
identical(DT[J(100L)], DT[y==100L]) # [1] TRUE
矢量掃描需要多少時間?
options(datatable.auto.index = FALSE)
system.time(DT[y == 100L]) ## 0.428 seconds
您無需將其轉換為字符向量(盡管整數會更有意義)
DT <- data.table(a = c(1, 3, 5, 9, 15), b = c("a", "c", "d", "e", "f"))
setkey(DT, a)
DT[J(c(3, 9))]
此外,如果您具有CRAN中的最新版本,則第二次在i中使用a將自動使用二進制搜索
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.