【问题标题】:Test if a value is unique in a vector in R测试一个值在 R 中的向量中是否唯一
【发布时间】:2015-08-21 22:34:26
【问题描述】:

让我们假设以下示例:

test<-c(1:5,3:7)

给了

test
[1] 1 2 3 4 5 3 4 5 6 7

我想要一个简单的函数,如果值在向量中是唯一的,则返回 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 

这使我更接近我想要的结果,但仍然不是所需的结果(相同长度的向量表明它在向量中是否唯一。)


所以有人知道如何更容易吗?

【问题讨论】:

    标签: r vector unique


    【解决方案1】:

    匹配运算符%in% 很有帮助:

    !test %in% test[duplicated(test)]
    

    【讨论】:

      【解决方案2】:

      您最初建议使用 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 按组执行操作时,这个玩法很不错,如果你的变量名称是行值或组列向量,语法会产生歧义。

      【讨论】:

        【解决方案3】:
        test<-c(1:5,3:7)
        isUnique <- function(vector){
                         return(!any(duplicated(vector)))
                   }
        isUnique(test)
        

        如果向量的值是唯一的,该函数将返回true

        【讨论】:

        • 您的函数没有返回预期的结果。它应该为向量的每个元素返回一个逻辑值,确定它在向量中是否唯一。
        【解决方案4】:

        虽然已经有一段时间了,但另一种选择。让数字说话:

        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
        

        【讨论】:

          猜你喜欢
          • 2018-04-24
          • 2021-12-06
          • 1970-01-01
          • 1970-01-01
          • 2013-08-20
          • 1970-01-01
          • 2020-09-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多