【问题标题】:How to re-sort different column groups to align each other, using a mutual column如何使用相互列重新排序不同的列组以相互对齐
【发布时间】:2020-11-13 12:42:52
【问题描述】:

我的数据乱序,这意味着某些行需要向上或向下移动以匹配特定顺序。具有特定值的列反映了正确的顺序。这些值对应于属于无序列组的列。

由于有一个相互列,我正在寻找一种方法来在数据框中“内部”重新排序。有没有一种简单的方法可以在一个%>% 管道中使用tidyr 或dplyr?

示例

我让 3 个人按照 1 到 5 分来评价他们喜欢狗、猫或兔子的程度。每个人回答问题的顺序与其他人不同。

set.seed(2020)

df <- data.frame(respondent_id = c("ttt", "ttt", "ttt",
                             "xxx", "xxx", "xxx",
                             "zzz", "zzz", "zzz"),
           animal = c("dog", "cat", "rabbit",
                          "dog", "cat", "rabbit",
                          "dog", "cat", "rabbit"),
           rating = sample(1:5, size = 9, replace = TRUE),
           order = c("cat", "rabbit", "dog",
                     "dog", "rabbit", "cat",
                     "rabbit", "cat", "dog"))

df

##   respondent_id animal rating  order
## 1           ttt    dog      4    cat
## 2           ttt    cat      4 rabbit
## 3           ttt rabbit      1    dog
## 4           xxx    dog      1    dog
## 5           xxx    cat      4 rabbit
## 6           xxx rabbit      2    cat
## 7           zzz    dog      1  rabbit
## 8           zzz    cat      5    cat
## 9           zzz rabbit      2    dog
  • animal 和 order 列是对齐数据的基础。
  • 当按respondent_id 分组时,我想将animal 和rating 列(一起)向上或向下移动,以便animal 中的值与order 中的值匹配。

期望的输出

  respondent_id animal rating  order
1           ttt    cat      4    cat
2           ttt rabbit      1 rabbit
3           ttt    dog      4    dog
4           xxx    dog      1    dog
5           xxx rabbit      2 rabbit
6           xxx    cat      4    cat
7           zzz rabbit      2 rabbit
8           zzz    cat      5    cat
9           zzz    dog      1    dog

【问题讨论】:

    标签: r dplyr tidyr


    【解决方案1】:

    使用slice 和match。

    library(tidyverse)
    
    df %>%
      group_by(respondent_id) %>%
      slice(match(order, animal)) %>%
      mutate(order = animal)
    #> # A tibble: 9 x 4
    #> # Groups:   respondent_id [3]
    #>   respondent_id animal rating order 
    #>   <chr>         <chr>   <int> <chr> 
    #> 1 ttt           cat         4 cat   
    #> 2 ttt           rabbit      1 rabbit
    #> 3 ttt           dog         4 dog   
    #> 4 xxx           dog         1 dog   
    #> 5 xxx           rabbit      2 rabbit
    #> 6 xxx           cat         4 cat   
    #> 7 zzz           rabbit      2 rabbit
    #> 8 zzz           cat         5 cat   
    #> 9 zzz           dog         1 dog  
    

    【讨论】:

    • 谢谢@Paul。您的解决方案适用于我在问题中提供的玩具数据,但由于某种原因,我无法将此方法应用于我的实际数据。你介意解释一下你的代码背后的原则吗?我了解match(order, animal) 做了什么,但不明白slice() 是如何操作的,最后的mutate 我也不清楚。谢谢:)
    • match(order, animal) 以正确的顺序为每个组获取行号。 slice 只是按照match 指定的顺序选择行。例如,选择的第一行是ttt, cat, 4, rabbit。 mutate(order = animal) 更新 order 列,使其变为 ttt, cat, 4, cat。
    猜你喜欢
    • 2016-03-17
    • 2012-04-03
    • 2021-12-27
    • 2019-07-18
    相关资源
    最近更新 更多