проверка значений переменных в соответствии с их метками во фрейме данных

#r

#r

Вопрос:

Мне нужно очистить данные таким образом, чтобы все значения находились в пределах заданного диапазона меток. Метки были установлены в SPSS, я использую пакет haven для их импорта в R. Я извлекаю метки с помощью:

 as.numeric(attr(data[[var]], "labels"))
  

даю мне вектор чисел. Теперь я выполняю итерацию по фрейму данных с целью сохранения всех имен переменных, которые содержат значения за пределами этого диапазона, чтобы получить представление о количестве случаев. Позже я мог бы автоматически заменить эти значения определенным отсутствующим кодом (например, -3).

 for (var in names(data)) {
  legalLabels <- as.numeric(attr(data[[var]], "labels"))
  if (!any(data[[var]] %in% legalLabels)) {
    result <- c(result, var)
  }
}
  

Результирующий вектор теперь содержит только символьные переменные, числовыми (или двойными / целочисленными) переменными пренебрегают.

Я также пытался:

 if (any(data[[var]] < min(legalLabels)) || any(data[[var]] > max(legalLabels))) {...}
  

безуспешно. Метки (под этим я подразумеваю числа, кодирующие ответ) обычно составляют от -4 до -1 для отсутствующих категорий и положительных чисел от 0 до 10, в зависимости от соответствующей переменной / количества ответов.

РЕДАКТИРОВАТЬ MWE:

 library("haven")
library("dplyr")
var1 <- labelled(c(1,1,-2,-1,2), c(NonResponse = -1, SystemMiss = -2, Yes = 1, No = 2), label="Test Variable 1")
var2 <- labelled(c(-1,2,-2,1,3), c(NonResponse = -1, SystemMiss = -2, Yes = 1, No = 2), label="Test Variable 2")

testdata <- data.frame(var1, var2)

result <- NULL
for (var in names(testdata)) {
  legalLabels <- as.numeric(attr(testdata[[var]], "labels")) # legalLabels => [1] -1 -2  1  2
  if (!any(data[[var]] %in% legalLabels)) {
    result <- c(result, var)
  }
}

>result
[1] "var1" "var2"

result should only include var2 since it contains a '3'
  

Комментарии:

1. Здравствуйте, не могли бы вы, пожалуйста, предоставить MWE с фиктивными данными?

2. готово, хотя у меня такое ощущение, что метки, которые были установлены в SPSS, ведут себя немного иначе.

3. Разве это не просто логическая проблема? Попробуйте заменить строку «if» на эту: if (sum(!testdata[[var]] %в% legalLabels)) {

4. Не работает, в результате все еще слишком много переменных. Я нашел очень неэффективный обходной путь (который также работает с любой логикой), так что пока все в порядке, но я уверен, что к этому должен быть гораздо более простой подход. Спасибо за попытку, хотя

Ответ №1:

Что я придумал:

 # only consider numerical variables
numData <- data %>% select_if(is.numeric)

# fill list with legal values corresponding to each respective variable
legalValues.lst <- list() # list of legal labels for each variable in df
counter <- 0
for (var in names(numData)) {
  legalValues <- as.numeric(attr(data[[var]], "labels"))
  legalValues <- c(legalValues, NA)  # always add NA as legal entry
  print(legalValues)
  counter <- counter   1
  print(counter)
  legalValues.lst[counter] <- list(legalValues)
}

# compare variable values to the corresponding vector of legal values from list above
counter <- 0
for (var in names(numData)) {
  counter <- counter   1
  
  tempVec <- NULL
  tempVec <- legalValues.lst[[counter]]
  
  print(var)
  print(any(!numData[[var]] %in% tempVec)) 
}

# prints all variable names and TRUE, if any value in that variable is NOT in the corresponding list entry of legal labels
#                               FALSE otherwise
# Narrows down variables that need to be looked into