Moh*_*hit 10 r data.table
我有这个向量,我想对其进行排序。
v1<-c(1,10,2,6,8,1,3,5,"a","ab","c","d","aa","abc","a a","a bc")。
然而,向量中同时包含数字和字符。所以我需要在字符之后进行数字排序。代码library(gtools); mixedsort(v1)完全按照要求解决了目的。
但我将其应用于大约 300 万个数据集。所以它效率不高,我需要一个可以更快处理它的代码。
解决方案应该是这样的。
> mixedsort(v1)
[1] "1" "1" "2" "3" "5" "6" "8" "10" "a" "a a" "a bc" "aa" "ab" "abc" "c" "d"
Run Code Online (Sandbox Code Playgroud)
多谢
Jon*_*ing 11
奇怪的是,这种笨拙的 dplyr/readr 方法比 dplyr/readr 方法快 27 倍mixedsort和 3 倍stringr::str_sort,因此很明显还有更多空间可以更快地完成此操作。
从那时起,我尝试了mixed_sort2@one,它通常会快一点。更快的方法仍然是在我原来的方法中使用as.numeric,以获得大约 100 倍的速度mixedsort。
# fake data, 3 million rows of characters and numbers
v1 <- sample(c(1:99, LETTERS), 3E6, replace = TRUE)
library(dplyr)
df_parse <- function(a) {
data.frame(a) %>%
mutate(num = readr::parse_number(a)) %>% # 4x faster if we use `as.numeric` instead
arrange(num, a) %>%
pull(a)
}
Run Code Online (Sandbox Code Playgroud)
编辑:从评论@one's添加
mixed_sort2 <- function(vec){
numeric_sort <- sort(as.numeric(vec))
character_sort <- sort(vec[is.na(as.numeric(vec))])
c(numeric_sort,character_sort)
}
Run Code Online (Sandbox Code Playgroud)
使用 dplyr 方法 + as.numeric 甚至更快:
df_asnumeric <- function(a) {
data.frame(a) %>%
mutate(num = as.numeric(a)) %>%
arrange(num, a) %>%
pull(a)
}
Run Code Online (Sandbox Code Playgroud)
microbenchmark::microbenchmark(
gtools::mixedsort(v1),
stringr::str_sort(v1, numeric = TRUE),
df_parse(v1),
mixed_sort2(v1),
df_asnumeric(v1),
times = 10, check = 'identical'
)
Unit: milliseconds
expr min lq mean median uq max neval
gtools::mixedsort(v1) 80676.6222 81825.6986 84672.9726 83671.3667 87335.5948 92225.717 10
stringr::str_sort(v1, numeric = TRUE) 4309.6739 4327.6529 4371.6771 4373.5337 4411.2573 4450.610 10
df_parse(v1) 777.4925 1031.4233 1133.8790 1052.9858 1073.2195 1683.851 10
mixed_sort2(v1) 3505.1529 3539.8577 3747.5667 3613.3492 4033.8569 4141.554 10
df_asnumeric(v1) 619.2090 635.7193 812.5554 864.3629 908.5028 1026.983 10
Run Code Online (Sandbox Code Playgroud)