Установить отсутствующие значения для нескольких помеченных переменных

Как установить отсутствующие значения для нескольких помеченных векторов в кадре данных. Я работаю с набором данных опроса от spss. Я имею дело с 20 различными переменными с теми же недостающими значениями. Поэтому хотелось бы найти способ использовать lapply() для выполнения этой работы, но я не могу.

Я на самом деле могу сделать это с базой R через as.numeric(), а затем recode(), но меня заинтриговали возможности гавани и маркированного класса, поэтому я хотел бы найти способ сделать это все в Хэдли tidyverse

Грубо представляющие интерес переменные выглядят так. Прошу прощения, если это основной вопрос, но я нахожу, что help documentaiton, связанный с приложением и помеченными пакетами, очень бесполезен.

library(haven)
library(labelled)
v1<-labelled(c(1,2,2,2,5,6), c(agree=1, disagree=2, dk=5, refused=6))
v2<-labelled(c(1,2,2,2,5,6), c(agree=1, disagree=2, dk=5, refused=6))
v3<-data.frame(v1=v1, v2=v2)
lapply(v3, val_labels)
lapply(v3, function(x) set_na_values(x, c(5,6)))

Ответы

Ответ 1

Хорошо, думаю, теперь я понимаю, что вы пытаетесь сделать...

то есть. Отметьте метки и значения как NA без удаления исходных импортированных данных...

См. дополнение к более подробному примеру, в котором используется файл общедоступных данных, чтобы показать пример, который использует dplyr для обновления нескольких столбцов, меток...

Предлагаемое решение

df <- data_frame(s1 = c(1,2,2,2,5,6), s2 = c(1,2,2,2,5,6)) %>%
  set_value_labels(s1 = c(agree=1, disagree=2, dk=5, refused=6), 
                   s2 = c(agree=1, disagree=2, dk = tagged_na("5"), refused = tagged_na("6"))) %>%
  set_na_values(s2 = c(5,6))


val_labels(df)
is.na(df$s1)
is.na(df$s2)
df

Результат решения:

> library(haven)
> library(labelled)
> library(dplyr)
> df <- data_frame(s1 = c(1,2,2,2,5,6), s2 = c(1,2,2,2,5,6)) %>%
+   set_value_labels(s1 = c(agree=1, disagree=2, dk=5, refused=6), 
+                    s2 = c(agree=1, disagree=2, dk = tagged_na("5"), refused = tagged_na("6"))) %>%
+   set_na_values(s2 = c(5,6))
> val_labels(df)
$s1
   agree disagree       dk  refused 
       1        2        5        6 

$s2
   agree disagree       dk  refused 
       1        2       NA       NA 

> is.na(df$s1)
[1] FALSE FALSE FALSE FALSE FALSE FALSE
> is.na(df$s2)
[1] FALSE FALSE FALSE FALSE  TRUE  TRUE
> df
# A tibble: 6 × 2
         s1        s2
  <dbl+lbl> <dbl+lbl>
1         1         1
2         2         2
3         2         2
4         2         2
5         5         5
6         6         6

Теперь мы можем манипулировать данными

mean(df$s1, na.rm = TRUE)
mean(df$s2, na.rm = TRUE)

> mean(df$s1, na.rm = TRUE)
[1] 3
> mean(df$s2, na.rm = TRUE)
[1] 1.75

Использовать маркированный пакет для удаления меток и заменить на R NA

Если вы хотите снять метки и заменить значениями R NA, вы можете использовать remove_labels(x, user_na_to_na = TRUE)

Пример:

df <- remove_labels(df, user_na_to_na = TRUE)
df

Результат:

> df <- remove_labels(df, user_na_to_na = TRUE) 
> df
# A tibble: 6 × 2
     s1    s2
  <dbl> <dbl>
1     1     1
2     2     2
3     2     2
4     2     2
5     5    NA
6     6    NA

-

Объяснение/Обзор формата SPSS:

IBM SPSS (приложение) может импортировать и экспортировать данные во многих форматах и ​​в непрямоугольных конфигурациях; однако набор данных всегда переводится в прямоугольный файл данных SPSS, известный как системный файл (с использованием расширения *.sav). Метаданные (информация о данных), такая как переменные форматы, отсутствующие значения и метки значений переменных и значений, хранятся в наборе данных.

Значения значений

База R имеет один тип данных, который эффективно поддерживает сопоставление между целыми числами и символьными метками: коэффициент. Это, однако, не является первичным использованием факторов: вместо этого они предназначены для автоматического создания полезных контрастов для линейных моделей. Факторы отличаются от помеченных значений, предоставляемых другими инструментами, важными способами:

SPSS и SAS могут обозначать числовые и символьные значения, а не только целые значения.

Отсутствующие значения

Все три инструмента (SPSS, SAS, Strata) предоставляют глобальное "системное недостающее значение", которое отображается как .. Это примерно эквивалентно Rs NA, хотя ни один из Stata и SAS не распространяет пропуски в числовых сравнениях: SAS обрабатывает недостающее значение как наименьшее возможное число (т.е. -inf), а Stata рассматривает его как максимально возможное число (например, inf).

Каждый инструмент также обеспечивает механизм записи нескольких типов пропусков:

  • У Stata есть "расширенные" отсутствующие значения, от .A до .Z.
  • SAS имеет "особые" отсутствующие значения, от .A до .Z plus._.
  • У SPSS есть пробелы "пользователь" без пробелов. Каждый столбец может объявлять до трех различных значений или диапазона значений (плюс одно отдельное значение), которые следует рассматривать как отсутствующие.

Определяемые пользователем недостающие значения

Пользовательские значения SPSSs работают по-разному с SAS и Stata. Каждый столбец может содержать до трех различных значений, которые считаются отсутствующими или диапазонами. Haven предоставляет labelled_spss() в качестве подкласса labelled() для моделирования этих дополнительных пользовательских пропусков.

x1 <- labelled_spss(c(1:10, 99), c(Missing = 99), na_value = 99)
x2 <- labelled_spss(c(1:10, 99), c(Missing = 99), na_range = c(90, Inf))

x1
#> <Labelled SPSS double>
#>  [1]  1  2  3  4  5  6  7  8  9 10 99
#> Missing values: 99
#> 
#> Labels:
#>  value   label
#>     99 Missing
x2
#> <Labelled SPSS double>
#>  [1]  1  2  3  4  5  6  7  8  9 10 99
#> Missing range:  [90, Inf]
#> 
#> Labels:
#>  value   label
#>     99 Missing

Отмеченные отсутствующие значения

Для поддержки расширенного Statas и специального отсутствующего значения SAS, haven реализует привязанный NA. Он делает это, используя внутреннюю структуру NA с плавающей точкой. Это позволяет этим значениям вести себя одинаково с NA в регулярных R-операциях, сохраняя при этом значение тега.

Интерфейс R для создания с тегами NA является немного неуклюжим, потому что, как правило, они создаются приютом для вас. Но вы можете создать свой собственный с tagged_na():

Важно:

Обратите внимание, что эти помеченные NA ведут себя одинаково с обычными NA, даже при печати. Чтобы увидеть их теги, используйте print_tagged_na():

Таким образом:

    library(haven)
    library(labelled)
    v1<-labelled(c(1,2,2,2,5,6), c(agree=1, disagree=2, dk=5, refused=6))
    v2<-labelled(c(1,2,2,2,5,6), c(agree=1, disagree=2, dk=tagged_na("5"), refused= tagged_na("6")))
    v3<-data.frame(v1 = v1, v2 = v2)
    v3
    lapply(v3, val_labels)

> v3
  x x.1
1 1   1
2 2   2
3 2   2
4 2   2
5 5   5
6 6   6
> lapply(v3, val_labels)
$x
   agree disagree       dk  refused 
       1        2        5        6 

$x.1
   agree disagree       dk  refused 
       1        2       NA       NA 

Осторожно:

Пользовательские значения SPSSs работают по-разному с SAS и Stata. Каждый столбец может содержать до трех различных значений, которые считаются отсутствующими или диапазонами. Haven предоставляет labelled_spss() в качестве подкласса labeled() для моделирования этих дополнительных пользовательских пропусков.

Я надеюсь, что это поможет

Позаботьтесь Т.

Литература:

Пример добавления с использованием общедоступных данных...

Отсутствующие значения SPSS Пример с использованием файла данных SPPS {hospital.sav}

Во-первых, давайте обязательно подчеркнем, что

  • Недопустимые значения системы - это значения, которые полностью отсутствуют в данных
  • Недопустимые значения пользователя - это значения, которые присутствуют в данных, но должны быть исключены из вычислений.

SPSS Просмотр данных...

Посмотрите изображение и данные... Данные SPSS, показанные в представлении переменной, показывают, что каждая строка имеет Ярлык [Столбец5], мы отмечаем, что строки с 10 по 14 имеют определенные значения, приписываемые для них [1..6] [Столбец 6], которые имеют атрибуты имени и что значения не указаны как Отсутствует [Столбец 7].

введите описание изображения здесь

Теперь посмотрим на представление данных SPSS:

Здесь мы можем отметить, что отсутствуют данные... (См. hilighted "." ). Ключевым моментом является то, что у нас Отсутствующие данные, но в настоящее время нет "Недопустимые значения пользователя"

введите описание изображения здесь

Теперь перейдем к R и загрузим данные в R

hospital_url <- "https://www.spss-tutorials.com/downloads/hospital.sav"
hospital <- read_sav(hospital_url, 
                     user_na = FALSE)
head(hospital,5)

# We're interested in columns 10 through 14...
head(hospital[10:14],5)

Результат

> hospital_url <- "https://www.spss-tutorials.com/downloads/hospital.sav"
> hospital <- read_sav(hospital_url, 
+                      user_na = FALSE)
> head(hospital,5)
# A tibble: 5 × 14
  visit_id patient_id first_name surname_prefix last_name    gender entry_date entry_time
     <dbl>      <dbl>      <chr>          <chr>     <chr> <dbl+lbl>     <date>     <time>
1    32943      23176    JEFFREY                 DIJKSTRA         1 2013-01-08   16:56:10
2    32944      20754       MARK        VAN DER      BERG         1 2013-02-01   14:24:45
3    32945      25419     WILLEM                VERMEULEN         1 2013-02-02   10:01:43
4    32946      21139      LINDA                  JANSSEN         0 2013-02-10   10:24:39
5    32947      25419     WILLEM                VERMEULEN         1 2013-02-10   18:05:59
# ... with 6 more variables: exit_moment <dttm>, doctor_rating <dbl+lbl>, nurse_rating <dbl+lbl>,
#   room_rating <dbl+lbl>, food_rating <dbl+lbl>, facilities_rating <dbl+lbl>

Столбцы с 10 по 14 содержат значения

1="Very Dissatisfied"
2="Dissatisfied"
3="Neutral"
4="Satisfied"
5="Very Satisfied"
6="Not applicable or don't want to answer"

следующим образом:

> head(hospital[10:14],5)
# A tibble: 5 × 5
  doctor_rating nurse_rating room_rating food_rating facilities_rating
      <dbl+lbl>    <dbl+lbl>   <dbl+lbl>   <dbl+lbl>         <dbl+lbl>
1             5            5           4           2                 3
2             4            5           4           3                 3
3             5            6           4           5                 4
4             4            5           5           4                 4
5             5            5           6           6                 6

Значения значений SPSS

> lapply(hospital[10], val_labels)
$doctor_rating
                     Very dissatisfied                           Dissatisfied 
                                     1                                      2 
                               Neutral                              Satisfied 
                                     3                                      4 
                        Very satisfied Not applicable or don't want to answer 
                                     5                                      6

ok, обратите внимание, что выше мы можем подтвердить, что мы импортировали метки значений.

Удалить неприменимые данные из данных опроса

Наша цель - удалить "Не применимо или не хотеть отвечать на записи, установив их как " Пользовательские значения NA ", т.е. SPSS отсутствующее значение.

Решение - Шаг 1 - Единая колонка

Мы хотим установить атрибут отсутствующего значения для нескольких столбцов в данных... Сначала сделайте это для одного столбца...

Примечание. Мы используем add_value_labels not set_value_labels, поскольку мы хотим добавить новую метку, а не полностью перезаписывать существующие метки...

d <- hospital
mean(d$doctor_rating, na.rm = TRUE)

d <- hospital %>% 
  add_value_labels( doctor_rating = c( "Not applicable or don't want to answer" 
                                       = tagged_na("6") )) %>%
  set_na_values(doctor_rating = 5)

val_labels(d$doctor_rating)
mean(d$doctor_rating, na.rm = TRUE)

> d <- hospital
> mean(d$doctor_rating, na.rm = TRUE)
[1] 4.322368
> d <- hospital %>% 
+   add_value_labels( doctor_rating = c( "Not applicable or don't want to answer" 
+                                        = tagged_na("6") )) %>%
+   set_na_values(doctor_rating = 6)
> val_labels(d$doctor_rating)
                     Very dissatisfied                           Dissatisfied 
                                     1                                      2 
                               Neutral                              Satisfied 
                                     3                                      4 
                        Very satisfied Not applicable or don't want to answer 
                                     5                                      6 
Not applicable or don't want to answer 
                                    NA 
> mean(d$doctor_rating, na.rm = TRUE)
[1] 4.097015

Решение - Шаг 2 - Теперь применитесь к нескольким столбцам...

mean(hospital$nurse_rating)
mean(hospital$nurse_rating, na.rm = TRUE)
d <- hospital %>% 
  add_value_labels( doctor_rating = c( "Not applicable or don't want to answer" 
                                       = tagged_na("6") )) %>%
  set_na_values(doctor_rating = 6) %>%
  add_value_labels( nurse_rating = c( "Not applicable or don't want to answer" 
                                     = tagged_na("6") )) %>%
  set_na_values(nurse_rating = 6)
mean(d$nurse_rating, na.rm = TRUE)

Результат

Обратите внимание, что nurse_rating содержит значения "NaN" и NA с тегами. Первый вызов mean() завершается с ошибкой, второй выполняется успешно, но включает в себя "Не применимо..." после того, как фильтр "Не применимо..." удалены...

> mean(hospital$nurse_rating)
[1] NaN
> mean(hospital$nurse_rating, na.rm = TRUE)
[1] 4.471429
> d <- hospital %>% 
+   add_value_labels( doctor_rating = c( "Not applicable or don't want to answer" 
+                                        = tagged_na("6") )) %>%
+   set_na_values(doctor_rating = 6) %>%
+   add_value_labels( nurse_rating = c( "Not applicable or don't want to answer" 
+                                      = tagged_na("6") )) %>%
+   set_na_values(nurse_rating = 6)
> mean(d$nurse_rating, na.rm = TRUE)
[1] 4.341085

Преобразовать помеченные NA в R NA

Здесь мы берем вышеуказанное помеченное NA и преобразуем в значения R NA.

d <- d %>% remove_labels(user_na_to_na = TRUE)

Ответ 2

Правильно ли это?

#Using replace to substitute 5 and 6 in v3 with NA
data.frame(lapply(v3, function(a) replace(x = a, list = a %in% c(5,6), values = NA)))
#   x x.1
#1  1   1
#2  2   2
#3  2   2
#4  2   2
#5 NA  NA
#6 NA  NA

Я знаю, что labelled_spss позволяет указать na_range или даже вектор na_values

#DATA
v11 = labelled_spss(x = c(1,2,2,2,5,6),
                    labels = c(agree=1, disagree=2, dk=5, refused=6),
                    na_range = 5:6)

#Check if v11 has NA values
is.na(v11)
#[1] FALSE FALSE FALSE FALSE  TRUE  TRUE

v22 = labelled_spss(x = c(1,2,2,2,5,6),
                    labels = c(agree=1, disagree=2, dk=5, refused=6),
                    na_range = 5:6)

#Put v11 and v22 in a list
v33 = list(v11, v22)

#Use replace like above
data.frame(lapply(X = v33, FUN = function(a) replace(x = a, list = is.na(a), values = NA)))
#   x x.1
#1  1   1
#2  2   2
#3  2   2
#4  2   2
#5 NA  NA
#6 NA  NA

Ответ 3

Определение пропущенных значений SPSS в стиле

Основные функции

Две основные функции в пакете labelled для управления потерянными значениями, заданными пользователем в стиле SPSS, - это na_values и na_range.

library(labelled)
v1 <-c(1,2,2,2,5,6)
val_labels(v1) <- c(agree=1, disagree=2, dk=5, refused=6)
na_values(v1) <- 5:6
v1

<Labelled SPSS double>
[1] 1 2 2 2 5 6
Missing values: 5, 6

Labels:
 value    label
     1    agree
     2 disagree
     5       dk
     6  refused

set_ * функции

Функции set_* в labelled предназначены для использования с magrittr/dplyr.

library(dplyr)
d <- tibble(v1 = c(1, 2, 2, 2, 5, 6), v2 = c(1:3, 1:3))
d <- d %>%
  set_value_labels(v1 = c(agree=1, disagree=2, dk=5, refused=6)) %>%
  set_na_values(v1 = 5:6)
d$v1

<Labelled SPSS double>
[1] 1 2 2 2 5 6
Missing values: 5, 6

Labels:
 value    label
     1    agree
     2 disagree
     5       dk
     6  refused

Каковы пользовательские отсутствующие значения?

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

mean(v1)
[1] 3

Вы можете легко преобразовать определяемые пользователем отсутствующие значения в правильные NA с помощью user_na_to_na.

mean(user_na_to_na(v1), na.rm = TRUE)
[1] 1.75

Существует очень мало функций, которые учитывали бы эту метаинформацию. См., Например, функцию freq из пакета questionr.

library(questionr)
freq(v1)
             n    % val%
[1] agree    1 16.7   25
[2] disagree 3 50.0   75
[5] dk       1 16.7   NA
[6] refused  1 16.7   NA
NA           0  0.0   NA

В чем разница с помеченными NA?

Цель помеченных NA, введенных haven, заключается в том, чтобы воспроизвести способ, которым Stata управляет отсутствующими значениями. Все отмеченные NAs считаются NA R NA.

Ответ 4

Не совсем уверен, что это то, что вы ищете:

v1 <- labelled(c(1, 2, 2, 2, 5, 6), c(agree = 1, disagree = 2, dk = 5, refused = 6))
v2 <- labelled(c(1, 2, 2, 2, 5, 6), c(agree = 1, disagree = 2, dk = 5, refused = 6))
v3 <- data_frame(v1 = v1, v2 = v2)

lapply(names(v3), FUN = function(x) {
  na_values(v3[[x]]) <<- 5:6
})

lapply(v3, na_values)

Последняя строка, возвращающая

$v1
[1] 5 6

$v2
[1] 5 6

Проверить отсутствующие значения:

is.na(v3$v1)
[1] FALSE FALSE FALSE FALSE  TRUE  TRUE

Ответ 5

Первый аргумент set_na_values - это кадр данных, а не вектор/столбец, поэтому ваша команда lapply не работает. Вы можете создать список аргументов для set_na_values для произвольного количества столбцов в вашем кадре данных, а затем вызвать его с помощью do.call, как показано ниже...

v1<-labelled(c(1,2,2,2,5,6), c(agree=1, disagree=2, dk=5, refused=6))
v2<-labelled(c(1,2,2,2,5,6), c(agree=1, disagree=2, dk=5, refused=6))
v3<-data.frame(v1=v1, v2=v2)
na_values(v3)

args <- c(list(.data = v3), setNames(lapply(names(v3), function(x) c(5,6)), names(v3)))
v3 <- do.call(set_na_values, args)
na_values(v3)

Обновление:. Вы также можете использовать форму назначения функции na_values в выражении lapply, так как она принимает вектор как первый аргумент вместо фрейма данных, например set_na_values...

library(haven)
library(labelled)
v1<-labelled(c(1,2,2,2,5,6), c(agree=1, disagree=2, dk=5, refused=6))
v2<-labelled(c(1,2,2,2,5,6), c(agree=1, disagree=2, dk=5, refused=6))
v3<-data.frame(v1=v1, v2=v2)
lapply(v3, val_labels)
na_values(v3)

v3[] <- lapply(v3, function(x) `na_values<-`(x, c(5,6)))
na_values(v3)

или даже использовать обычную версию na_values в команде lapply, просто вернув "фиксированный" вектор...

library(haven)
library(labelled)
v1<-labelled(c(1,2,2,2,5,6), c(agree=1, disagree=2, dk=5, refused=6))
v2<-labelled(c(1,2,2,2,5,6), c(agree=1, disagree=2, dk=5, refused=6))
v3<-data.frame(v1=v1, v2=v2)
lapply(v3, val_labels)
na_values(v3)

v3[] <- lapply(v3, function(x) { na_values(x) <- c(5,6); x } )
na_values(v3)

и эта идея может использоваться внутри цепочки dplyr, либо применяя ко всем переменным, либо применяя к любым столбцам с помощью инструментов выбора dplyr...

library(haven)
library(labelled)
library(dplyr)
v1<-labelled(c(1,2,2,2,5,6), c(agree=1, disagree=2, dk=5, refused=6))
v2<-labelled(c(1,2,2,2,5,6), c(agree=1, disagree=2, dk=5, refused=6))
v3<-data.frame(v1=v1, v2=v2)
lapply(v3, val_labels)
na_values(v3)

v4 <- v3 %>% mutate_all(funs(`na_values<-`(., c(5,6))))
na_values(v4)

v5 <- v3 %>% mutate_each(funs(`na_values<-`(., c(5,6))), x)
na_values(v5)

Ответ 6

Вы можете использовать очень простое решение при использовании base R:

v3[v3 == 5 ] <- NA
v3[v3 == 6 ] <- NA

Но если вы ищете очень быстрое решение, вы можете использовать подход data.table.

library(data.table)

setDT(v3)

for(j in seq_along(v3)) { 
            set(v3, i=which(v3[[j]] %in% c(5,6)), j=j, value=NA) 
            }