r中基于因子水平索引的排序数据帧

时间:2020-06-16 23:31:55

标签: r dataframe dplyr tidyr

我有一个如下所示的数据框:

df <- data.frame(Name = c("BB", "AA", "AA", "BB", "DD", "AA", "DD", "DD", "CC"), 
             string = c("a11", "a120", "a120", "a8", "a45", "a11", "a140", "a8", "a45") ,
             value = rnorm(9, mean = 0, 1))

Name  string   value

 BB    a11  0.5912728
 AA   a120  0.5885065
 AA   a120 -0.5287264
 BB     a8  0.6932831
 DD    a45 -0.2892612
 AA    a11  1.0441365
 DD   a140 -0.5091612
 DD     a8 -0.3358695
 CC    a45  0.5598616

我想对df重新排序,以便根据数字部分pf字符串列对其进行排序。

我正在尝试以下命令:

string <- unique(as.character(df$string))
sorted.ind <- sort(as.numeric(gsub('a', '', string)), index.return = T)$ix
df$string <- factor(df$string, levels = string[sorted.ind])  

但是它也不对表重新排序。

这是我想要的输出:

Name  string  value

BB     a8  0.6932831
DD     a8 -0.3358695
BB    a11  0.5912728
AA    a11  1.0441365
DD    a45 -0.2892612
CC    a45  0.5598616
AA   a120  0.5885065
AA   a120 -0.5287264
DD   a140 -0.5091612

有人知道我该如何修正我的代码?

谢谢

3 个答案:

答案 0 :(得分:2)

您可以删除数字并按以下方式排列:

playbyplay

答案 1 :(得分:2)

您可以如下使用dplyr。这是另一个答案的变体,不使用stringr

library(dplyr)
df %>%
   arrange(as.numeric(gsub("\\D+", "", string)))

##   Name string       value
## 1   BB     a8  0.35120965
## 2   DD     a8  0.54526648
## 3   BB    a11 -0.90101120
## 4   AA    a11  1.65637910
## 5   DD    a45  0.42240082
## 6   CC    a45 -0.30438594
## 7   AA   a120 -0.05781699
## 8   AA   a120 -1.83615123
## 9   DD   a140 -1.82698618

除了Name以外,您还可以按string进行排序。

so.df %>%
  arrange(
      as.numeric(gsub("\\D+", "", string)),
      Name
  )
##   Name string       value
## 1   BB     a8  0.35120965
## 2   DD     a8  0.54526648
## 3   AA    a11  1.65637910
## 4   BB    a11 -0.90101120
## 5   CC    a45 -0.30438594
## 6   DD    a45  0.42240082
## 7   AA   a120 -0.05781699
## 8   AA   a120 -1.83615123
## 9   DD   a140 -1.82698618

答案 2 :(得分:0)

您可以使用gtools::mixedorder

df[gtools::mixedorder(df$string), ]

#  Name string      value
#4   BB     a8 -0.9128301
#8   DD     a8 -0.5483317
#1   BB    a11 -1.2260433
#6   AA    a11 -0.4713301
#5   DD    a45 -0.3376227
#9   CC    a45 -1.0200505
#2   AA   a120 -0.2612332
#3   AA   a120 -1.1606446
#7   DD   a140 -0.7210719

此外,如果string中还有其他字符,并且您只对数字感兴趣,则可以使用parse_number提取数字并order

df[order(readr::parse_number(df$string)),]