在 R 中清理排名选择调查数据
Cleaning rank-choice survey data in R
我有我在 R 中处理的调查数据,其中包括向受访者提供选项列表并要求他们对前五名进行排名的问题。数据如下所示:
head(data)
responseid ChoiceA ChoiceB ChoiceC ChoiceD ChoiceE ChoiceF
1 001 5 2 1 NA 4 3
2 002 NA 4 3 5 2 1
3 003 3 1 NA 2 4 5
4 004 NA 5 2 1 3 4
我想重塑它,使其看起来像这样:
head(data_new)
responseid first second third fourth fifth
1 001 C B F E A
2 002 F E C B D
3 003 B D A E F
4 004 D C E F B
执行此操作的有效方法是什么,最好是在 tidyverse 中?我觉得答案将涉及根据其他列的名称更改新列中的值,我不知道该怎么做。
我也正在从 SurveyGizmo 中提取这些数据,所以如果有人对设置它的方法有建议,以便数据首先按照我想要的方式导出到 csv,我将不胜感激以及。谢谢!
我们可以重塑为 'long' 格式,然后将其旋转为 'wide' 格式
library(dplyr)
library(tidyr)
library(english)
df1 %>%
pivot_longer(cols = -responseid, values_drop_na = TRUE) %>%
separate(name, into = c("name1", "name2"), "(?<=[a-z])(?=[A-Z])") %>%
mutate(value = as.character(ordinal(value))) %>%
pivot_wider(names_from = value, values_from = name2)
要点是您想要旋转更长的时间,稍微清理一下,然后使用排名作为列名称而不是选项来旋转更宽。这是与 akrun 类似的方法,尽管我认为考虑到五个选择的限制,硬编码序数列名称不那么复杂。
library(tidyverse)
tbl <- read_table2(
"responseid ChoiceA ChoiceB ChoiceC ChoiceD ChoiceE ChoiceF
001 5 2 1 NA 4 3
002 NA 4 3 5 2 1
003 3 1 NA 2 4 5
004 NA 5 2 1 3 4"
)
tbl %>%
pivot_longer(
cols = -responseid,
names_to = "choice",
values_to = "rank",
values_drop_na = TRUE
) %>%
mutate(
choice = str_remove(choice, "Choice"),
rank = c("first", "second", "third", "fourth", "fifth")[as.integer(rank)]
) %>%
pivot_wider(names_from = rank, values_from = choice) %>%
select(responseid, first, second, third, fourth, fifth)
#> # A tibble: 4 x 6
#> responseid first second third fourth fifth
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 001 C B F E A
#> 2 002 F E C B D
#> 3 003 B D A E F
#> 4 004 D C E F B
由 reprex package (v0.3.0)
于 2020 年 3 月 4 日创建
出于兴趣,生成正确顺序的基 R 中的单行代码:
gsub("Choice", "", t(apply(data_new, 1, function(x) names(data_new)[-1][order(x[-1])]))[,1:5])
#> [,1] [,2] [,3] [,4] [,5]
#> 1 "C" "B" "F" "E" "A"
#> 2 "F" "E" "C" "B" "D"
#> 3 "B" "D" "A" "E" "F"
#> 4 "D" "C" "E" "F" "B"
我有我在 R 中处理的调查数据,其中包括向受访者提供选项列表并要求他们对前五名进行排名的问题。数据如下所示:
head(data)
responseid ChoiceA ChoiceB ChoiceC ChoiceD ChoiceE ChoiceF
1 001 5 2 1 NA 4 3
2 002 NA 4 3 5 2 1
3 003 3 1 NA 2 4 5
4 004 NA 5 2 1 3 4
我想重塑它,使其看起来像这样:
head(data_new)
responseid first second third fourth fifth
1 001 C B F E A
2 002 F E C B D
3 003 B D A E F
4 004 D C E F B
执行此操作的有效方法是什么,最好是在 tidyverse 中?我觉得答案将涉及根据其他列的名称更改新列中的值,我不知道该怎么做。
我也正在从 SurveyGizmo 中提取这些数据,所以如果有人对设置它的方法有建议,以便数据首先按照我想要的方式导出到 csv,我将不胜感激以及。谢谢!
我们可以重塑为 'long' 格式,然后将其旋转为 'wide' 格式
library(dplyr)
library(tidyr)
library(english)
df1 %>%
pivot_longer(cols = -responseid, values_drop_na = TRUE) %>%
separate(name, into = c("name1", "name2"), "(?<=[a-z])(?=[A-Z])") %>%
mutate(value = as.character(ordinal(value))) %>%
pivot_wider(names_from = value, values_from = name2)
要点是您想要旋转更长的时间,稍微清理一下,然后使用排名作为列名称而不是选项来旋转更宽。这是与 akrun 类似的方法,尽管我认为考虑到五个选择的限制,硬编码序数列名称不那么复杂。
library(tidyverse)
tbl <- read_table2(
"responseid ChoiceA ChoiceB ChoiceC ChoiceD ChoiceE ChoiceF
001 5 2 1 NA 4 3
002 NA 4 3 5 2 1
003 3 1 NA 2 4 5
004 NA 5 2 1 3 4"
)
tbl %>%
pivot_longer(
cols = -responseid,
names_to = "choice",
values_to = "rank",
values_drop_na = TRUE
) %>%
mutate(
choice = str_remove(choice, "Choice"),
rank = c("first", "second", "third", "fourth", "fifth")[as.integer(rank)]
) %>%
pivot_wider(names_from = rank, values_from = choice) %>%
select(responseid, first, second, third, fourth, fifth)
#> # A tibble: 4 x 6
#> responseid first second third fourth fifth
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 001 C B F E A
#> 2 002 F E C B D
#> 3 003 B D A E F
#> 4 004 D C E F B
由 reprex package (v0.3.0)
于 2020 年 3 月 4 日创建出于兴趣,生成正确顺序的基 R 中的单行代码:
gsub("Choice", "", t(apply(data_new, 1, function(x) names(data_new)[-1][order(x[-1])]))[,1:5])
#> [,1] [,2] [,3] [,4] [,5]
#> 1 "C" "B" "F" "E" "A"
#> 2 "F" "E" "C" "B" "D"
#> 3 "B" "D" "A" "E" "F"
#> 4 "D" "C" "E" "F" "B"