Проверка данных: проверка реальных данных на основе контрольных данных - PullRequest
0 голосов
/ 04 февраля 2019

У меня есть набор данных, содержащий такие переменные, как имя, национальность и пол.Я хочу проверить правильность половой переменной этого набора данных на основе набора эталонных данных, который содержит правильные значения пола для каждой комбинации имя-национальность.

Рассмотрим два примеранаборы данных ниже:

# 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 голосов
/ 04 февраля 2019

Мы могли бы использовать 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
.
0 голосов
/ 04 февраля 2019

Мы могли бы left_join обе таблицы name и nationality, а затем проверить оба столбца sex и присвоить значение 1 в случае, если они являются разными значениями и replace несовпадающими NA с0.

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 merge

df1 <- merge(df_real, df_check, by = c("name", "nationality"), all.x = TRUE)
df1$check <- +(df1$sex.x != df1$sex.y)
df1$check[is.na(df1$check)] <- 0

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

Порядок отображения выходных данных отличается от базы R.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...