将排名信息折叠成单列

Collapsing ranked information into single column

我有一项调查,人们对一些学校进行排名。调查结果在多个列中包含 1 和 2。我需要将这些折叠成一个人的第一和第二选择。 这是我拥有的数据示例。

df1 <- tibble(Person  = c(1 , 2 , 3 , 4 , 5 , 6 , 7), 
School1 = c(NA, 1 , 2 , NA, NA, NA, 1 ), 
School2 = c(NA, 2 , 1 , NA, NA, 1 , NA), 
School3 = c(1 , NA, NA, NA, NA, 2 , NA),
School4 = c(2 , NA, NA, 1 , 2 , NA, NA), 
School5 = c(NA, NA, NA, 2 , 1 , NA, 2))

  Person School1 School2 School3 School4 School5
   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1      1      NA      NA       1       2      NA
2      2       1       2      NA      NA      NA
3      3       2       1      NA      NA      NA
4      4      NA      NA      NA       1       2
5      5      NA      NA      NA       2       1
6      6      NA       1       2      NA      NA
7      7       1      NA      NA      NA       2

这是我需要的结果。

df2 <- tibble(Person  = c(1 , 2 , 3 , 4 , 5 , 6 , 7), 
School1 = c(NA, 1 , 2 , NA, NA, NA, 1 ), 
School2 = c(NA, 2 , 1 , NA, NA, 1 , NA), 
School3 = c(1 , NA, NA, NA, NA, 2 , NA), 
School4 = c(2 , NA, NA, 1 , 2 , NA, NA), 
School5 = c(NA, NA, NA, 2 , 1 , NA, 2), 
Firstchoice = c('School3', 'School1', 'School2', 'School4', 'School5', 'School2', 'School1'), 
Secondchoice = c('School4', 'School2', 'School1', 'School5', 'School4', 'School3', 'School5'))

  Person School1 School2 School3 School4 School5 Firstchoice Secondchoice
   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl> <chr>       <chr>       
1      1      NA      NA       1       2      NA School3     School4     
2      2       1       2      NA      NA      NA School1     School2     
3      3       2       1      NA      NA      NA School2     School1     
4      4      NA      NA      NA       1       2 School4     School5     
5      5      NA      NA      NA       2       1 School5     School4     
6      6      NA       1       2      NA      NA School2     School3     
7      7       1      NA      NA      NA       2 School1     School5 

我查看了 mutate,并使用了 for 循环,但是我不知道如何让它们工作,因为它们需要对列进行内联更新。

如有任何帮助,我们将不胜感激。

一个 tidyverse 可能是:

 df1 %>%
  gather(var, val, -Person) %>%
  mutate(val = ifelse(val == 1, "Firstchoice", 
                      ifelse(val == 2, "Secondchoice", NA_character_))) %>%
  na.omit() %>%
  spread(val, var) %>%
  left_join(df1, by = c("Person" = "Person"))

  Person Firstchoice Secondchoice School1 School2 School3 School4 School5
   <dbl> <chr>       <chr>          <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1      1 School3     School4           NA      NA       1       2      NA
2      2 School1     School2            1       2      NA      NA      NA
3      3 School2     School1            2       1      NA      NA      NA
4      4 School4     School5           NA      NA      NA       1       2
5      5 School5     School4           NA      NA      NA       2       1
6      6 School2     School3           NA       1       2      NA      NA
7      7 School1     School5            1      NA      NA      NA       2

使用 tidyr 小菜一碟:

choices <- gather(df1, key = "school", value = "choice", -Person, na.rm=TRUE)
choices <- arrange(choices, Person, choice)