首页 > 解决方案 > R 仅订购一个因子水平(或列,如果之后)以影响从长到宽的顺序(使用价差)

问题描述

将我的数据集从长更改为宽后出现问题(使用spread, 来自 tidyr 库Result_Type)后,我遇到了问题。我有以下示例df:

Group<-c("A","A","A","B","B","B","C","C","C","D", "D")
Result_Type<-c("Final.Result", "Verification","Test", "Verification","Final.Result","Fast",
               "Verification","Fast", "Final.Result", "Test", "Final.Result")
Result<-c(7,1,8,7,"NA",9,10,12,17,50,11)
df<-data.frame(Group, Result_Type, Result)

df
   Group  Result_Type Result
1      A Final.Result      7
2      A Verification      1
3      A         Test      8
4      B Verification      7
5      B Final.Result     NA
6      B         Fast      9
7      C Verification     10
8      C         Fast     12
9      C Final.Result     17
10     D         Test     50
11     D Final.Result     11

在专栏Result_type中,有许多可能的结果类型,在某些数据集中我有 Result_Type ,这不会出现在其他数据集中。但是,一个级别:Final.Result确实出现在每个数据集中。

另外:这是示例数据,但实际数据有许多不同的列,并且由于我使用的数据集不同,我使用了spread了(来自 tidyr 库),因此我不必提供除目标列之外的任何特定列名.

library("tidyr")
df_spread<-spread(df, key = Result_Type, value = Result)

  Group Fast Final.Result Test Verification
1     A <NA>            7    8            1
2     B    9           NA <NA>            7
3     C   12           17 <NA>           10
4     D <NA>           11   50         <NA>

我想要的是,一旦我将数据集从长转换为宽,Final.Result是第一列,其余列的排列方式并不重要,所以我希望它是这样的(不调用任何名称其他列分布,或使用订单索引号):

  Group Final.Result Fast Test Verification
1     A            7 <NA>    8            1
2     B           NA    9 <NA>            7
3     C           17   12 <NA>           10
4     D           11 <NA>   50         <NA>

我看到一些答案表明您可以反转展开列的顺序,或关闭展开的顺序,但这并不能确保Final.Resultspread始终是级别的第一列。

我希望我说清楚,解释起来有点复杂。如果有人需要额外的信息,我会很乐意解释更多!

标签: rsortingtidyrspread

解决方案


spreadkey按列的因子水平顺序创建列。在 tidyverse 中,forcats::fct_relevel有一个用于重新排列因子水平的便利功能。默认情况下,您指定的级别将被移到前面。

library(dplyr)
library(tidyr)

...

levels(df$Result_Type)
#> [1] "Fast"         "Final.Result" "Test"         "Verification"

跟注fct_relevel"Final.Result"作为第一个级别,其余级别保持之前的顺序。

reordered <- df %>%
  mutate(Result_Type = forcats::fct_relevel(Result_Type, "Final.Result"))

levels(reordered$Result_Type)
#> [1] "Final.Result" "Fast"         "Test"         "Verification"

将其添加到您的管道中Final.Result作为传播后的第一列。

df %>%
  mutate(Result_Type = forcats::fct_relevel(Result_Type, "Final.Result")) %>%
  spread(key = Result_Type, value = Result)
#>   Group Final.Result Fast Test Verification
#> 1     A            7 <NA>    8            1
#> 2     B           NA    9 <NA>            7
#> 3     C           17   12 <NA>           10
#> 4     D           11 <NA>   50         <NA>

reprex 包(v0.2.1)于 2018 年 12 月 14 日创建


推荐阅读