使用 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
我有一大组调查响应数据,但在清理时遇到了问题。
在调查开始时,受访者 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