繁体   English   中英

在 r 中以多列为条件重新编码 NA

[英]Recoding NAs conditional on multiple columns in r

我有很多调查数据,其中受访者被问到许多不同的多项选择题,他们可以选择多个答案。 调查软件将每个问题编码为多个变量,这些变量可以具有答案或 NA 的值。 但是,NA 并不是很合适,因为除非个人跳过问题,否则不选择答案真的意味着“不”。 我想重新编码所有此类问题以解决此问题,以便我可以分析数据。 如果个人跳过了 NA 应该支持的问题,但如果他们至少点击了多项选择中的一个,那么 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() ,但没有成功。

如果我们对多列执行此操作,一种选择是使用pivot_longer重新pivot_longer为“long”格式并应用该函数

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, .)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM