如何对半数字字符串进行排序?

时间:2017-06-01 10:09:10

标签: r

我有以下形状的字符向量:

fld <- c('20*20', '100*100', '200*200', '50*50', '1000*1000', '250*250')

我需要根据星号之前的数字值对元素进行排序。

sort(fld)给出:

[1] "100*100" "1000*1000" "20*20" "200*200" "250*250" "50*50"

而不是理想的:

[1] "20*20" "50*50" "100*100" "200*200" "250*250" "1000*1000"

我已经准备好以下表达方式:

fld[
  charmatch(  
    paste(
      as.character(sort(as.integer( 
        gsub('\\*.{2,4}', '', fld)
      ))),
      '*', sep = ''
    ),
    fld)
  ]

但我敢打赌,有更短/更容易/更自然的方式...

2 个答案:

答案 0 :(得分:4)

基础R方法:

fld[order(as.numeric(sub("\\*.*", "", fld)))]
#[1] "20*20"     "50*50"     "100*100"   "200*200"   "250*250"   "1000*1000"

这将删除*fld的每个元素后面的任何内容,将结果部分转换为数字并计算顺序。这用于索引/排序原始矢量。

只是为了好的衡量,这是另一种提取向量的第一部分的方法(仅限数字):

fld[order(as.numeric(sub("^(\\d+)(.*)", "\\1", fld)))]
#[1] "20*20"     "50*50"     "100*100"   "200*200"   "250*250"   "1000*1000"

答案 1 :(得分:1)

我们可以使用parse_number中的readrparse_number将在*order之前提取数字以获取索引,然后使用它来排序原始向量

library(readr)
fld[order(parse_number(fld))]
#[1] "20*20"     "50*50"     "100*100"   "200*200"   "250*250"   "1000*1000"

或者更有效的方法是使用stri_extract_first中的stringi提取数字部分,转换为数字,order基于此原始字符串

library(stringi)
fld[order(as.integer(stri_extract_first_regex(fld, "[0-9]+")))]
#[1] "20*20"     "50*50"     "100*100"   "200*200"   "250*250"   "1000*1000"