使用 Tidyverse 将调查数据中的 "Other - Write in" 替换为文本

Replacing "Other - Write in" with written in text in survey data with Tidyverse

我有一大组调查响应数据,但在清理时遇到了问题。

在调查开始时,受访者 select 一组(颜色,在本例中),并有条件地显示相同的问题(在本例中,"Rank your favorite three fruits out of this list, or write in another fruit"),但条件是根据他们选择的颜色,他们会看到不同的水果清单以供选择。

最初,数据看起来像这样。颜色和答案选择的每种组合都有一列,值是他们给该答案选择的排名,如果他们将 "other" 列为其中之一,他们在 "other" 列中写入文本响应他们的选择:

# A tibble: 11 x 8
   responseid color   red_q1_a  red_q1_b  red_q1_c  red_q1_other  red_q1_other_answer blue_q1_a
        <dbl> <chr>     <dbl>    <dbl>    <dbl>        <dbl>    <chr>                   <dbl>
 1         34 red           2        1       NA            3    "Pomegranates"             NA
 2         35 blue         NA       NA       NA           NA    NA                          1
 3         36 green        NA       NA       NA           NA    NA                         NA
 4         37 purple       NA       NA       NA           NA    NA                         NA
 5         38 red           1       NA        3            2    "Watermelon"               NA
 6         39 green        NA       NA       NA           NA    NA                         NA
 7         40 purple       NA       NA       NA           NA    NA                         NA
 8         41 blue         NA       NA       NA           NA    NA                         NA
 9         42 blue         NA       NA       NA           NA    NA                          2
10         43 green        NA       NA       NA           NA    NA                         NA
11         44 red           1        3        2           NA    NA                         NA   

对于第一个问题,我设法清理了数据,使其看起来像这样:

# A tibble: 11 x 6
   responseid color  q1_first_choice   q1_second_choice   q1_third_choice   q1_other_answer
        <dbl> <chr>  <chr>             <chr>              <chr>             <chr>          
 1         34 red    q1_red_b           q1_red_a            q1_red_other       "Pomegranate"    
 2         35 blue   q1_blue_a          q1_blue_c           q1_blue_b          NA             
 3         36 green  q1_green_other     q1_green_b          q1_green_a         "Tangerine"      
 4         37 purple q1_purple_b        q1_purple_a         q1_purple_c        NA             
 5         38 red    q1_red_a           q1_red_other        q1_red_c           "Watermelon"     
 6         39 green  q1_green_a         q1_green_c          q1_green_b         NA             
 7         40 purple q1_purple_b        q1_purple_a         q1_purple_c        NA             
 8         41 blue   q1_blue_c          q1_blue_a           q1_blue_other      "Blueberries"    
 9         42 blue   q1_blue_a          q1_blue_c           q1_blue_b          NA             
10         43 green  q1_green_c         q1_green_b          q1_green_a         NA             
11         44 red    q1_red_b           q1_red_a            q1_red_c           NA       

我还有两个要执行的步骤,但我不确定如何有效地执行它们。首先,我想用写入的文本值替换任何 "other" 选项的排名选项,因此它看起来像这样:

   responseid color q1_first_choice    q1_second_choice    q1_third_choice 
          34 red    q1_red_b           q1_red_a            "Pomegranate"    
          35 blue   q1_blue_c          q1_blue_a           q1_blue_b          
          36 green  "Tangerine"        q1_green_b          q1_green_a         
          37 purple q1_purple_b        q1_purple_a         q1_purple_c        
          38 red    q1_red_a           "Watermelon"        q1_red_c           
          39 green  q1_green_a         q1_green_c          q1_green_b                      
          40 purple q1_purple_b        q1_purple_a         q1_purple_c                     
          41 blue   q1_blue_c          q1_blue_b           "Blueberries"    
          42 blue   q1_blue_a          q1_blue_c           q1_blue_b                       
          43 green  q1_green_c         q1_green_b          q1_green_a                      
          44 red    q1_red_b           q1_red_a            q1_red_c                  

我在为此尝试使用有效的 ifelse 或 case_when 时遇到了问题 - 我想要一个函数来表示,对于列 q1_first_choice:q1_third_choice 中的所有值,如果它们包含字符串 "other",将它们替换为该行中 q1_other_answer 列中的值。

最后,我想用它们的实际值替换答案代码("q1_blue_c" 等)。我认为使用 case_when 函数就足够简单了,但是对于很长的案例列表,是否有一种有效的方法可以将该转换应用于多行?我确实有一本调查密码本,将所有变量名称链接到他们的实际答案选择(即,q1_red_a 是 "Apple",q1_red_b 是 "Banana",等等,通过数百个的选择)。有没有一种好方法将该列表存储为 R 中的某种对象,并设置 ifelse/case_when 语句来引用它,而不是在函数中键入整个列表?

你能把你的第二个问题作为一个单独的问题来问吗?最好让每个问题单独存在,以便未来的读者更容易找到每个特定问题的解决方案。

对于第一个问题,想法是使用 if_else(),如果包含单词 "other"(使用 str_detect()),则替换为 q1_other_answer,否则保留原样。然后使用 mutate_at() 将其应用于您想要的变量。

library(tidyverse)

mydf <- tribble(
~responseid, ~color,  ~q1_first_choice,   ~q1_second_choice,   ~q1_third_choice,   ~q1_other_answer,
34, "red   " , "q1_red_b     "  ,    "q1_red_a    "    ,    "q1_red_other "   ,   "Pomegranate"    ,
35, "blue  " , "q1_blue_a    "  ,    "q1_blue_c   "    ,    "q1_blue_b    "   ,   NA             ,
36, "green " , "q1_green_other" ,    "q1_green_b  "    ,    "q1_green_a   "   ,   "Tangerine"      ,
37, "purple" , "q1_purple_b  "  ,    "q1_purple_a "    ,    "q1_purple_c  "   ,   NA             ,
38, "red   " , "q1_red_a     "  ,    "q1_red_other"    ,    "q1_red_c     "   ,   "Watermelon"     ,
39, "green " , "q1_green_a   "  ,    "q1_green_c  "    ,    "q1_green_b   "   ,   NA             ,
40, "purple" , "q1_purple_b  "  ,    "q1_purple_a "    ,    "q1_purple_c  "   ,   NA             ,
41, "blue  " , "q1_blue_c    "  ,    "q1_blue_a   "    ,    "q1_blue_other"   ,   "Blueberries"    ,
42, "blue  " , "q1_blue_a    "  ,    "q1_blue_c   "    ,    "q1_blue_b    "   ,   NA             ,
43, "green " , "q1_green_c   "  ,    "q1_green_b  "    ,    "q1_green_a   "   ,   NA             ,
44, "red   " , "q1_red_b     "  ,    "q1_red_a    "    ,    "q1_red_c     "   ,   NA       
) %>% 
  mutate_if(is.character, str_trim)

mutate_at(mydf, vars(ends_with("choice")), ~ if_else(str_detect(., "other"), q1_other_answer, .))

# A tibble: 11 x 6
   responseid color  q1_first_choice q1_second_choice q1_third_choice q1_other_answer
        <dbl> <chr>  <chr>           <chr>            <chr>           <chr>          
 1         34 red    q1_red_b        q1_red_a         Pomegranate     Pomegranate    
 2         35 blue   q1_blue_a       q1_blue_c        q1_blue_b       NA             
 3         36 green  Tangerine       q1_green_b       q1_green_a      Tangerine      
 4         37 purple q1_purple_b     q1_purple_a      q1_purple_c     NA             
 5         38 red    q1_red_a        Watermelon       q1_red_c        Watermelon     
 6         39 green  q1_green_a      q1_green_c       q1_green_b      NA             
 7         40 purple q1_purple_b     q1_purple_a      q1_purple_c     NA             
 8         41 blue   q1_blue_c       q1_blue_a        Blueberries     Blueberries    
 9         42 blue   q1_blue_a       q1_blue_c        q1_blue_b       NA             
10         43 green  q1_green_c      q1_green_b       q1_green_a      NA             
11         44 red    q1_red_b        q1_red_a         q1_red_c        NA