упорядочение кадра данных на основе показателей уровней факторов в r - PullRequest
0 голосов
/ 17 июня 2020

У меня есть фрейм данных, который выглядит следующим образом:

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 так, чтобы он упорядочивался на основе столбца строки numeri c part 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 ]

2 голосов
/ 17 июня 2020

Вы можете использовать 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 голосов
/ 17 июня 2020

Вы можете вырезать нецифровые символы и расположить их так:

library(stringr)
library(dplyr)

df %>%
  arrange(as.numeric(str_remove(string, "\\D+")))

  Name string       value
4   BB     a8  1.74351093
8   DD     a8  0.41802240
1   BB    a11  0.61559079
6   AA    a11  0.63900177
5   DD    a45 -1.87046411
9   CC    a45 -0.44398027
2   AA   a120 -0.84459958
3   AA   a120  0.01800482
7   DD   a140 -0.88140002
0 голосов
/ 17 июня 2020

Вы можете использовать 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)),]
...