【问题标题】:How do you verify whether a set of variables uniquely identifies the data in dplyr/tidyverse?如何验证一组变量是否唯一标识 dplyr/tidyverse 中的数据?
【发布时间】:2021-01-06 18:19:52
【问题描述】:

dplyr 有没有办法验证给定的一组变量是否唯一标识了管道中的数据?这对于验证数据在我认为它们在合并之前的级别是唯一的等很有用。

例如,这个数据集由变量 v 和 z 唯一标识。

myData <- tibble(
    v=c(1, 1, 2, 3, 4), 
    z=c(0, 1, 1, 1, 1), 
    y=rnorm(5)
)

我希望能够在对 pip 进行操作后验证 v 和 z 唯一标识数据。例如:

myData %>%
    mutate(y_squared=y^2) %>%
    verify(any(duplicated(c('v', 'z')))==0)

但是这种方法的各种迭代会引发不同的错误。提前感谢您的帮助。

【问题讨论】:

    标签: r dplyr tidyverse


    【解决方案1】:

    我会使用基本 R 的 anyDuplicated(它返回重复的数量,因此我们将其与 0 进行比较)。

    myData %>%
        {anyDuplicated(select(., v, z)) == 0}
    # TRUE
    

    如果这些列中没有重复,它将返回TRUE,如果有重复,它将返回FALSE

    【讨论】:

    • 太酷了。对不起,基本问题,但是:1)表达式周围的括号 {} 有什么作用? 2)如果我在 anyDuplicated 命令上方的管道中编辑 myData,“。”将数据传递给 anyDuplicated 是更新的数据还是原始数据?
    • 大括号用于操作顺序。 ==%&gt;% 具有更高的优先级,所以如果没有大括号,R 将不幸地尝试比较anyDuplicated(...) == 0 管道输入数据! {} 将里面的内容组合为一个表达式,因此 R 知道要通过管道输入整个内容。
    • . 指的是您输入的任何数据,应该是您要检查的任何数据。我的问题中的示例显示了如何检查数据框,但结果将为 TRUE 或 FALSE。如果您想检查管道中间的某些内容,如果一切正常,则继续,但如果出现问题则停止,我们可以编写一个包装器...这是您想要的吗?
    • 哇非常感谢您的帮助 Gregor 这真的很有帮助。从本周开始是 R 的新手。我想我可以使用它:``` myData %>% mutate... %>% filter... %>% verify(anyDuplicated(select(.,v,z))==0) ``` 所以即使没有 {},它看起来也能正常工作。你知道为什么会这样吗?将已经编辑(变异和过滤)的数据读入操作似乎很慢,这正是我想要的。但要确保我理解语法。
    • 在您的 cmets 中,verify() 包含 anyDuplicated(...) == 0,因此在我的回答中,verify(){} 的作用相同。
    【解决方案2】:

    这是使用add_count的一种可能性:

    myData %>%
      add_count(v, z) %>%
      filter(n != 1)
    

    【讨论】:

    • 谢谢!不过,我希望以一种实际上不编辑数据的方式来执行此操作(根据您拥有的过滤器命令)。您知道是否有任何方法可以简单地验证这些变量是否唯一地标识了数据?
    【解决方案3】:

    这显示了重复的行:

    myData %>%
        mutate(y_squared=y^2) %>%
        filter(duplicated(.[ ,c("v", "z")]))
    

    【讨论】:

    • 谢谢!不过,我希望以一种实际上不编辑数据的方式来执行此操作(根据您拥有的过滤器命令)。您知道是否有任何方法可以简单地验证这些变量是否唯一地标识了数据?
    【解决方案4】:

    或者你可以签入base R:

    length(unique(paste(myData$v, myData$z))) == nrow(myData)
    

    如果你想使用管道语句:

    library(tidyverse)
    
    myData <- tibble(
        v=c(1, 1, 2, 3, 4), 
        z=c(0, 1, 1, 1, 1), 
        y=rnorm(5) )
    
    myData %>% summarize(is_v_z_unique = length(unique(paste(.$v, .$z))) == nrow(myData))
    #> # A tibble: 1 x 1
    #>   is_v_z_unique
    #>   <lgl>        
    #> 1 TRUE
    

    如果您只想要 1(表示 TRUE)和 0(表示 FALSE),情况如下:

    library(tidyverse)
    
    myData <- tibble(
        v=c(1, 1, 2, 3, 4), 
        z=c(0, 1, 1, 1, 1), 
        y=rnorm(5) )
    
    myData %>% summarize(is_v_z_unique = length(unique(paste(.$v, .$z))) == nrow(myData)) %>% 
        unlist() %>% as.numeric() 
    #> [1] 1
    

    reprex package (v0.3.0) 于 2021-01-06 创建

    【讨论】:

    • 知道了,但没有办法在管道内执行此操作?我希望能够执行上述操作,然后通过验证数据的唯一性来结束管道。感谢您的帮助!
    • 如果您想在 dplyr 工作流程中执行此操作,那么输出需要以某种方式适合您的工作流程。如果 myData$v 和 myData$z 唯一标识您的数据,您打算如何报告?
    • 我只是希望它输出一个 1/0,如果数据在该级别是唯一的,则它是 True。通过管道进行汇总是有道理的,但我试图以一种实际上不编辑数据的方式来执行此操作(汇总命令将其折叠为 1 行)。即我只想在管道中验证代码在 v-z 级别是唯一的,如果不是,则将代码错误输出。这有意义吗?
    • 由于当前命令没有重新分配任何值,它实际上并没有改变任何数据。我添加了代码,所以它吐出 1 表示 TRUE 和 0 表示 FALSE。
    • 对不起,我想我不清楚。我希望在对数据进行其他更改的管道中执行此操作,然后最后检查数据是否唯一。我看到您的代码如何验证唯一性,但该管道的输出只是 1/0。这意味着我需要在自己的管道中进行检查,而不是在我对数据进行其他编辑的现有管道中进行检查,对吧?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    • 1970-01-01
    • 2023-01-23
    相关资源
    最近更新 更多