我有一个包含变量的数据集,例如姓名,国籍和性别。我想根据基准数据集检查此数据集的性别变量的正确性,该基准数据集包含每个名称-国籍-组合的正确性别值。
请考虑以下两个示例数据集:
# 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()
函数的更简单的解决方案,不幸的是我无法弄清楚。
答案 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_join
和name
上的两个表都被选中,然后检查两个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中有所不同。