测试一个值在 R 中的向量中是否唯一
Test if a value is unique in a vector in R
让我们假设以下示例:
test<-c(1:5,3:7)
这给出了
test
[1] 1 2 3 4 5 3 4 5 6 7
我想要一个简单的函数,如果该值在向量中是唯一的,则 returns 为 TRUE。
[1] TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE
我试过的:
unique(test)
只返回唯一值,包括那些重复的值。
duplicated(test)
还我
[1] FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE FALSE FALSE
这显然不是所需的结果,因为函数会按顺序测试重复的观察结果,并且第一次出现不计为重复。我当然可以通过包含 fromLast = T
来反转控制序列并创建两个向量。在这两个中,我可以创建第三个来指示真正的唯一值……但这相当复杂。
table(test)
允许我计算每个值的出现次数
test
1 2 3 4 5 6 7
1 1 2 2 2 1 1
这让我更接近我想要的结果,但仍然不是所需的结果(一个相同长度的向量表明它在向量中是否唯一。)
所以有人知道如何更容易地做到这一点吗?
匹配运算符 %in%
很有帮助:
!test %in% test[duplicated(test)]
test<-c(1:5,3:7)
isUnique <- function(vector){
return(!any(duplicated(vector)))
}
isUnique(test)
如果向量的值是唯一的
,函数将return为真
您最初的建议是将 duplicated()
的 fromLast = TRUE
开关与 OR 运算符结合使用,这似乎是一个简单而优雅的解决方案:
test <- c(1:5, 3:7)
test
## [1] 1 2 3 4 5 3 4 5 6 7
duplicated(test) # incorrect result
## [1] FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE FALSE FALSE
duplicated(test) | duplicated(test, fromLast = TRUE) # correct result
## [1] FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE
当使用 data.table 按组执行操作时,这个游戏很好,如果您的变量名称是行值或组列向量,语法会使它变得不明确。
虽然已经有一段时间了,但另一种选择。让数字说话:
library(microbenchmark)
library(DescTools)
set.seed(1789)
x <- sample(round(rnorm(1000), 3), 1e5, replace = TRUE)
bm <- microbenchmark(
"!AllDuplicated(x)" = !AllDuplicated(x),
"!x %in% x[duplicated(x)]" = !x %in% x[duplicated(x)]
)
print(bm , unit="relative" , digits=3 , order="median" )
Unit: relative
expr min lq mean median uq max neval cld
!AllDuplicated(x) 1.00 1.00 1.00 1.00 1.00 1.000 100 a
!x %in% x[duplicated(x)] 1.44 1.43 1.16 1.45 1.52 0.143 100 a
于是我们看到了DescTools::AllDuplicated(),顺便实现了joaoal公式化的解法思路,x为数字取胜,字符处理失败(虽然只针对中位数,不是运行的平均值)。
z <- as.character(x)
bm <- microbenchmark(
"!AllDuplicated(z)" = AllDuplicated(z),
"!z %in% z[duplicated(z)]" = !z %in% z[duplicated(z)]
)
print(bm , unit="relative" , digits=3 , order="median")
Unit: relative
expr min lq mean median uq max neval cld
!z %in% z[duplicated(z)] 1.00 1.00 1.00 1.00 1.00 1.00 100 a
!AllDuplicated(z) 1.09 1.09 0.97 1.06 0.68 1.16 100 a
让我们假设以下示例:
test<-c(1:5,3:7)
这给出了
test
[1] 1 2 3 4 5 3 4 5 6 7
我想要一个简单的函数,如果该值在向量中是唯一的,则 returns 为 TRUE。
[1] TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE
我试过的:
unique(test)
只返回唯一值,包括那些重复的值。
duplicated(test)
还我
[1] FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE FALSE FALSE
这显然不是所需的结果,因为函数会按顺序测试重复的观察结果,并且第一次出现不计为重复。我当然可以通过包含 fromLast = T
来反转控制序列并创建两个向量。在这两个中,我可以创建第三个来指示真正的唯一值……但这相当复杂。
table(test)
允许我计算每个值的出现次数
test
1 2 3 4 5 6 7
1 1 2 2 2 1 1
这让我更接近我想要的结果,但仍然不是所需的结果(一个相同长度的向量表明它在向量中是否唯一。)
所以有人知道如何更容易地做到这一点吗?
匹配运算符 %in%
很有帮助:
!test %in% test[duplicated(test)]
test<-c(1:5,3:7)
isUnique <- function(vector){
return(!any(duplicated(vector)))
}
isUnique(test)
如果向量的值是唯一的
,函数将return为真您最初的建议是将 duplicated()
的 fromLast = TRUE
开关与 OR 运算符结合使用,这似乎是一个简单而优雅的解决方案:
test <- c(1:5, 3:7)
test
## [1] 1 2 3 4 5 3 4 5 6 7
duplicated(test) # incorrect result
## [1] FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE FALSE FALSE
duplicated(test) | duplicated(test, fromLast = TRUE) # correct result
## [1] FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE
当使用 data.table 按组执行操作时,这个游戏很好,如果您的变量名称是行值或组列向量,语法会使它变得不明确。
虽然已经有一段时间了,但另一种选择。让数字说话:
library(microbenchmark)
library(DescTools)
set.seed(1789)
x <- sample(round(rnorm(1000), 3), 1e5, replace = TRUE)
bm <- microbenchmark(
"!AllDuplicated(x)" = !AllDuplicated(x),
"!x %in% x[duplicated(x)]" = !x %in% x[duplicated(x)]
)
print(bm , unit="relative" , digits=3 , order="median" )
Unit: relative
expr min lq mean median uq max neval cld
!AllDuplicated(x) 1.00 1.00 1.00 1.00 1.00 1.000 100 a
!x %in% x[duplicated(x)] 1.44 1.43 1.16 1.45 1.52 0.143 100 a
于是我们看到了DescTools::AllDuplicated(),顺便实现了joaoal公式化的解法思路,x为数字取胜,字符处理失败(虽然只针对中位数,不是运行的平均值)。
z <- as.character(x)
bm <- microbenchmark(
"!AllDuplicated(z)" = AllDuplicated(z),
"!z %in% z[duplicated(z)]" = !z %in% z[duplicated(z)]
)
print(bm , unit="relative" , digits=3 , order="median")
Unit: relative
expr min lq mean median uq max neval cld
!z %in% z[duplicated(z)] 1.00 1.00 1.00 1.00 1.00 1.00 100 a
!AllDuplicated(z) 1.09 1.09 0.97 1.06 0.68 1.16 100 a