验证data.table
密钥是否唯一的最快方法是什么?有没有比更快或更惯用的方法
has_unique_key <- function(.data){
uniqueN(.data, by = key(.data)) == nrow(.data)
}
为了避免开销性能成本,该函数可以假定.data
是data.table
并具有密钥。我对验证.data
具有唯一密钥的性能更感兴趣;如果密钥不是唯一的,则速度就不那么重要了。
小插图密钥和基于快速二叉搜索的子集指出,不会强制执行密钥唯一性:
- 不强制唯一性,即允许重复的键值。由于行是按键排序的,因此键列中的任何重复项都将连续显示。
但我还没有找到任何表明data.table
知道或不知道它的密钥是唯一的。
唯一键
set.seed(1)
z <- sample(1:1e5)
DT <- data.table(z = z)
setkey(DT, z)
DT[, a := sample(letters, nrow(DT), replace = TRUE)]
DT[, b := rnorm(.N)]
microbenchmark(nrow(DT) == nrow(unique(DT, by = key(DT))),
uniqueN(DT[, key(DT), with=F]) == nrow(DT),
uniqueN(DT, by = key(DT)) == nrow(DT))
Unit: microseconds
expr min lq mean median uq max neval cld
nrow(DT) == nrow(unique(DT, by = key(DT))) 1731.766 2786.937 3678.377 3152.114 3870.119 9875.277 100 c
uniqueN(DT[, key(DT), with = F]) == nrow(DT) 777.637 1113.149 1543.786 1276.236 1614.307 3809.281 100 b
uniqueN(DT, by = key(DT)) == nrow(DT) 541.515 734.570 1123.801 825.826 1756.612 2356.406 100 a
非唯一
set.seed(1)
z <- c(1e5, sample(1:1e5))
DT <- data.table(z = z)
setkey(DT, z)
DT[, a := sample(letters, nrow(DT), replace = TRUE)]
DT[, b := rnorm(.N)]
microbenchmark(nrow(DT) == nrow(unique(DT, by = key(DT))),
uniqueN(DT[, key(DT), with=F]) == nrow(DT),
uniqueN(DT, by = key(DT)) == nrow(DT))
Unit: microseconds
expr min lq mean median uq max neval cld
nrow(DT) == nrow(unique(DT, by = key(DT))) 2925.026 4051.878 5340.941 4535.266 5464.095 12479.852 100 c
uniqueN(DT[, key(DT), with = F]) == nrow(DT) 1148.688 1515.972 1875.423 1670.627 1981.892 4843.822 100 b
uniqueN(DT, by = key(DT)) == nrow(DT) 857.450 1018.580 1332.697 1099.746 1301.685 3470.156 100 a
确定可疑的组合键是否唯一只需测试 nrow(( 的 group_by 返回与其输入数据框相同的 nrow((
library(dplyr)
z <- data.frame(Repeated=sample(LETTERS[1:5], size=5, replace=TRUE),
NOT_Repeated=sample(LETTERS[1:5], size=5, replace=FALSE))
z
test_unique <- z %>% group_by(Repeated) %>% summarise(Count=n_distinct(Repeated))
test_unique
nrow(z) == nrow(test_unique)
test_unique <- z %>% group_by(NOT_Repeated) %>% summarise(Count=n_distinct(NOT_Repeated))
test_unique
nrow(z) == nrow(test_unique)