Рекодирование NA условно на нескольких столбцах в r - PullRequest
1 голос
/ 22 декабря 2019

У меня много данных опроса, где респондентам задавали много разных вопросов с несколькими вариантами ответов, на которые они могли выбрать несколько ответов. Программное обеспечение опроса закодировало каждый вопрос в виде нескольких переменных, которые могут иметь значения либо ответа, либо NA. НО не совсем подходит, так как, если человек не пропустил вопрос, отказ от выбора действительно означает «нет». Я хочу перекодировать все вопросы этого типа, чтобы исправить это, чтобы я мог анализировать данные. Если человек пропустил вопросы, которые должны задать НС, но если они нажали хотя бы на один из нескольких вариантов, то НС должны быть «нет». Пример ниже:

library(tidyverse)
df <- tibble(SC_1 = c("yes", "yes", NA, "yes", "yes", NA, "yes", "yes", NA, "yes"),
             SC_2 = c("yes", NA, NA, NA, "yes", "yes", NA, "yes", NA, "yes"),
             RF_1 = c("gas", "gas", NA, "gas", "gas", NA, "gas", "gas", NA, "gas"),
             RF_2 = c("electricity", NA, NA, NA, "electricity", "electricity", NA, "yes", NA, "electricity"))

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

df %>% mutate(SC_1_recode = ifelse(is.na(SC_1) & is.na(SC_2), SC_1, 
                                   ifelse(is.na(SC_1),"no", SC_1)),
              SC_2_recode = ifelse(is.na(SC_1) & is.na(SC_2), SC_2, 
                                   ifelse(is.na(SC_2),"no", SC_2)),
              RF_1_recode = ifelse(is.na(RF_1) & is.na(RF_2), RF_1, 
                                   ifelse(is.na(RF_1),"no", RF_1)),
              RF_2_recode = ifelse(is.na(RF_1) & is.na(RF_2), RF_2, 
                                   ifelse(is.na(RF_2),"no", RF_2)))

#   SC_1  SC_2  RF_1  RF_2        SC_1_recode SC_2_recode RF_1_recode RF_2_recode
#   <chr> <chr> <chr> <chr>       <chr>       <chr>       <chr>       <chr>      
# 1 yes   yes   gas   electricity yes         yes         gas         electricity
# 2 yes   NA    gas   NA          yes         no          gas         no         
# 3 NA    NA    NA    NA          NA          NA          NA          NA         
# 4 yes   NA    gas   NA          yes         no          gas         no         
# 5 yes   yes   gas   electricity yes         yes         gas         electricity
# 6 NA    yes   NA    electricity no          yes         no          electricity
# 7 yes   NA    gas   NA          yes         no          gas         no         
# 8 yes   yes   gas   yes         yes         yes         gas         yes        
# 9 NA    NA    NA    NA          NA          NA          NA          NA         
#10 yes   yes   gas   electricity yes         yes         gas         electricity

Но это кажется громоздким, учитывая, что у меня есть десятки вопросов такого рода, и ониу всех есть эта проблема. Есть идеи? Я пробовал mutate_if(), но никуда не попал.

1 Ответ

0 голосов
/ 22 декабря 2019

Если мы делаем это для нескольких столбцов, одним из вариантов является преобразование в «длинный» формат с помощью pivot_longer и применение функции

library(dplyr)
library(tidyr)
library(stringr)
f1 <- function(x) case_when(all(is.na(x))~ NA_character_,
            is.na(first(x)) ~ "no", 
              TRUE ~  first(x))
df %>% 
  mutate(rn = row_number()) %>%
  pivot_longer(cols = -rn, names_to = c(".value", "group"), names_sep = "_")%>%
  group_by(rn) %>% 
  mutate_at(vars(SC:RF), f1) %>% 
  ungroup %>%      
  filter(group == 1) %>%
  select(SC:RF) %>% 
  rename_all(~ str_c(., "_1_recode")) %>%
  bind_cols(df, .)
# A tibble: 10 x 6
#   SC_1  SC_2  RF_1  RF_2        SC_1_recode RF_1_recode
#   <chr> <chr> <chr> <chr>       <chr>       <chr>      
# 1 yes   yes   gas   electricity yes         gas        
# 2 yes   <NA>  gas   <NA>        yes         gas        
# 3 <NA>  <NA>  <NA>  <NA>        <NA>        <NA>       
# 4 yes   <NA>  gas   <NA>        yes         gas        
# 5 yes   yes   gas   electricity yes         gas        
# 6 <NA>  yes   <NA>  electricity no          no         
# 7 yes   <NA>  gas   <NA>        yes         gas        
# 8 yes   yes   gas   yes         yes         gas        
# 9 <NA>  <NA>  <NA>  <NA>        <NA>        <NA>       
#10 yes   yes   gas   electricity yes         gas        

Набор данных также можно разбить на разныегруппы наборов данных на основе имен столбцов и применения функции

library(purrr)
df %>% 
    split.default(str_remove(names(.), "_\\d+$")) %>% 
    map_dfc(~ 
          .x %>% 
              transmute(!! str_c(names(.)[1], "_1_recode") := 
                coalesce(!!! .) %>% 
                  replace(., !is.na(.) & is.na(!! rlang::sym(names(.)[1])), "no"))) %>%
    bind_cols(df, .)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...