Ошибка if_else со столбцом haven_labelled из-за неправильного класса - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть следующие данные:

dat <- structure(list(value = structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
                                        label = "value: This is my label",
                                        labels = c(`No` = 0, `Yes` = 1),
                                        class = "haven_labelled"),
                      group = structure(c(1, 2, 1, 1, 2, 3, 3, 1, 3, 1, 3, 3, 1, 2, 3, 2, 1, 3, 3, 1),
                                        label = "my group",
                                        labels = c(first = 1, second = 2, third = 3),
                                        class = "haven_labelled")),
                 row.names = c(NA, -20L),
                 class = c("tbl_df", "tbl", "data.frame"),
                 label = "test.sav")

Как видите, в данных используется специальный класс из пакета убежища tidyverse, так называемые labelled столбцы.

Теперь я хочу перекодировать мою исходную переменную value так, чтобы:

, если группа равнялась 1, значение оставалось прежним, в противном случае оно должно отсутствовать

Я пробовал следующее , но получаю ошибку:

dat_new <- dat %>%
  mutate(value = if_else(group != 1, NA, value))
# Error: `false` must be a logical vector, not a `haven_labelled` object

Я дошел до того, что понял, что if_else из dplyr требует, чтобы проверки true и false в команде if_else были одного и того же класса, и поскольку для класса не существует эквивалента NA помеченный (например, как NA_real_ для двойников), код, вероятно, завершается ошибкой, верно?

Итак, как я могу перекодировать мои исходные переменные и сохранить метки ?

Я знаю, что мог бы изменить свой код выше и заменить if_else базовой версией R ifelse. Однако это удаляет все метки и приводит столбец значений к цифре c один.

Ответы [ 2 ]

1 голос
/ 29 апреля 2020

Вы можете попробовать dplyr::case_when для случаев, когда group == 1. Если не найдено ни одного случая, возвращается NA:

dat %>% mutate(value = case_when(group == 1 ~ value))
1 голос
/ 29 апреля 2020

Вы можете создать значение NA в классе haven_labelled с помощью этого уродливого кода:

haven::labelled(NA_real_, labels = attr(dat$value, "labels"))

Я бы рекомендовал написать для этого функцию, например,

labelled_NA <- function(value) 
  haven::labelled(NA_real_, labels = attr(value, "labels"))

и тогда код вашего мутирования не так уж уродлив:

dat_new <- dat %>%
  mutate(value = if_else(group != labelled_NA(value), value)) 

Тогда вы получите

> dat_new[1:5,]
# A tibble: 5 x 2
      value      group
  <dbl+lbl>  <dbl+lbl>
1   NA      1 [first] 
2   NA      2 [second]
3    0 [No] 1 [first] 
4    0 [No] 1 [first] 
5   NA      2 [second]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...