数据验证:根据基准数据检查实际数据

时间:2019-02-04 14:22:17

标签: r validation dataframe

我有一个包含变量的数据集,例如姓名,国籍和性别。我想根据基准数据集检查此数据集的性别变量的正确性,该基准数据集包含每个名称-国籍-组合的正确性别值。

请考虑以下两个示例数据集:

# Real data set that should be validated
df_real <- data.frame(name = c("Kevin", "Marie", "Rute", NA, "Charles", "Bruno"),
                      nationality = c("USA", "DE", "PT", "FR", NA, "PT"),
                      sex = c(1, 2, 1, 2, 2, NA)) # 1 = Male; 2 = Female

# Correct data set as basement for validation
df_check <- data.frame(name = c("Alfons", "Kevin", "Kevin", "Kevin", "Rute", "Charles", "Bruno", "Anne"),
                       nationality = c("FR", "USA", "DE", "PT", "PT", "FR", "PT", "LU"),
                       sex = c(1, 1, 1, 1, 2, 1, 1, 2))

应基于df_real检查df_check的列性别是否正确。在该示例中,所有性别值在第三行旁边都是正确的(即Rute应该是df_real中的女性)。

需要考虑其他几个数据条件:

  • df_real有多个NA。如果df_real中某行的任何值为NA,则应跳过对该行的检查。
  • df_real中出现的名称并不总是在df_check中出现。在这种情况下,也应跳过此行的检查。

最终输出应为伪向量,其长度为nrow(df_real),其中包含0(即值正确或跳过了检查)和1(即值不正确)。 >

预期输出:

output_check <- c(0, 0, 1, 0, 0, 0)

我尝试使用复杂的for循环和if条件解决此问题。但是,由于我的数据非常大,因此需要大量的计算时间。我确信必须有一个基于apply()函数的更简单的解决方案,不幸的是我无法弄清楚。

2 个答案:

答案 0 :(得分:2)

我们可以使用data.table对“名称”,“国籍”进行联接以创建“检查”列

library(data.table)
setDT(df_real)[df_check, check :=  +(sex !=  i.sex), on = .(name, nationality)]
df_real[is.na(check), check := 0]
df_real
#      name nationality sex check
#1:   Kevin         USA   1     0
#2:   Marie          DE   2     0 
#3:    Rute          PT   1     1
#4:    <NA>          FR   2     0
#5: Charles        <NA>   2     0
#6:   Bruno          PT  NA     0

答案 1 :(得分:1)

我们可以left_joinname上的两个表都被选中,然后检查两个nationality列,并为它们分配不同的值,如果{{1} }与0不匹配的sex

replace

对基数R NA使用相同的逻辑

library(tidyverse)

df_real %>% 
  left_join(df_check, by = c("name" = "name","nationality" = "nationality")) %>%
  mutate(check = +(sex.x != sex.y)) %>%
  replace_na(list(check = 0)) #%>%
  #select(-sex.x, -sex.y) #if you don't need sex columns


#     name nationality sex.x sex.y check
#1   Kevin         USA     1     1     0
#2   Marie          DE     2    NA     0
#3    Rute          PT     1     2     1
#4    <NA>          FR     2    NA     0
#5 Charles        <NA>     2    NA     0
#6   Bruno          PT    NA     1     0

输出显示的顺序在基本R中有所不同。