经过几个函数,我得到了一个表,该表已对字符进行排序,其中一些以“(”或“ [”开头,后跟数字(间隔,来自数据的cut(x))
我要实现的是一个由invervals的起始值决定的顺序,因此(100,124]不比(70,100]早(请参见示例) 编辑:column1(类)的顺序应保持不变。
好吧,我尝试使用data.table中的order和setorder来做到这一点,但到目前为止失败了。我想我需要先用strsplit拆分该列,然后按其第一个元素进行排序,但这不能成为“最佳”解决方案
test <- data.frame(class = c("class1", "class1", "class1", "class1", "class2", "class2", "class2", "class2", "class2", "class2", "class2", "class2", "class2"),
attr = c("1","2","4","5","(100,124]", "(124,180]" ,"(180,Inf]", "(37,50]" , "(5,37]" , "(50,56]" , "(56,70]" ,"(70,100]" ,"[0,5]" ),
value = c(415.14,115.13,422.52,37.07,167.40,135.04,67.01,280.03,81.18,237.83,285.62,302.63,3.37))
目标:
class attr value
class1 1 415.14
class1 2 115.13
class1 4 422.52
class1 5 37.07
class2 [0,5] 3.37
class2 (5,37] 81.18
class2 (37,50] 280.03
class2 (50,56] 237.83
class2 (56,70] 285.62
class2 (70,100] 302.63
class2 (100,124] 167.40
class2 (124,180] 135.04
class2 (180,Inf] 67.01
答案 0 :(得分:2)
1)base R 用空字符串替换逗号及其后的所有内容以及所有非数字。将其转换为数字并计算将其排序的索引o
。最后用test
下标o
。
o <- with(test, order(class, as.numeric(gsub(",.*|\\D", "", attr))))
test[o, ]
给予:
class attr value
1 class1 1 977.0947
2 class1 2 299.9418
3 class1 4 1398.7519
4 class1 5 170.8434
13 class2 [0,5] 299.1390
9 class2 (5,37] 326.5092
8 class2 (37,50] 923.6778
10 class2 (50,56] 734.9950
11 class2 (56,70] 820.7536
12 class2 (70,100] 779.0926
5 class2 (100,124] 308.5136
6 class2 (124,180] 234.6386
7 class2 (180,Inf] 100.1264
1a)也适用。它匹配一个可选的初始非数字,后跟数字,然后再加上其他任何东西,并全部替换为数字。然后按上述步骤进行。
o <- with(test, order(class, as.numeric(gsub("^\\D?(\\d+).*", "\\1", attr))))
test[o, ]
2)dplyr
也可以使用dplyr arrange
来完成上述操作:
library(dplyr)
test %>% arrange(class, attr %>% gsub(",.*|\\D", "", .) %>% as.numeric)
2a)的一种变化是删除(/ [和逗号等部分在单独的子语句中:
test %>%
arrange(class, attr %>%
sub("^\\D", "", .) %>%
sub(",.*", "", .) %>%
as.numeric)
答案 1 :(得分:2)
带有tidyverse
library(tidyverse)
test %>%
arrange(class, as.numeric(str_extract(attr, "\\d+")))
# class attr value
#1 class1 1 415.14
#2 class1 2 115.13
#3 class1 4 422.52
#4 class1 5 37.07
#5 class2 [0,5] 3.37
#6 class2 (5,37] 81.18
#7 class2 (37,50] 280.03
#8 class2 (50,56] 237.83
#9 class2 (56,70] 285.62
#10 class2 (70,100] 302.63
#11 class2 (100,124] 167.40
#12 class2 (124,180] 135.04
#13 class2 (180,Inf] 67.01
注意:没有结实的种子
答案 2 :(得分:0)
stringi
备选方案,使用与@G相同的逻辑。格洛腾迪克的解决方案。它提取attr
列中的第一个数字序列:
o2 <- order(test$class, as.numeric(stringi::stri_extract_first_regex(test$attr, "\\d+")))
test[o2, ]
class attr value
1 class1 1 977.0947
2 class1 2 299.9418
3 class1 4 1398.7519
4 class1 5 170.8434
13 class2 [0,5] 299.1390
9 class2 (5,37] 326.5092
8 class2 (37,50] 923.6778
10 class2 (50,56] 734.9950
11 class2 (56,70] 820.7536
12 class2 (70,100] 779.0926
5 class2 (100,124] 308.5136
6 class2 (124,180] 234.6386
7 class2 (180,Inf] 100.1264