#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