如何将数字向量转换为包含间隔的字符串

3
我有一个看起来很简单的问题,但我一直没有找到一个好的解决方法。如果我有一个数字向量,这里表示年份,例如c(2000,2001,2002,2003, 2005, 2007,2008,2009,2010),我希望它返回一个字符串,但不是所有数字,因为这将非常长,而是用可能的间隔返回一个字符串,所以一个字符串会返回"2000-2003, 2005, 2007-2010"。有没有一般情况下容易解决这个问题的方法?

使用?cut阅读cut函数的帮助。 - Marco Sandri
不要忘记通过点击向下箭头按钮下方的灰色勾号来接受最佳答案。 - acylam
2个回答

2
这是一种实现方式。
nums <- c(2000,2001,2002,2003, 2005, 2007,2008,2009,2010)

numRanges <- function(nums){
  nums <- sort(nums) #sort in case they are in random order!
  paste(tapply(nums, 
               cumsum(c(1, diff(nums)!=1)), #grouping indicator
               function(x) paste(min(x), #first number of each group
                                 ifelse(length(x)==1, "", max(x)), #last number if required
                                 sep = ifelse(length(x)==1, "", "-"))),
        collapse=", ") #paste the above together into a single string
}

numRanges(nums)
"2000-2003, 2005, 2007-2010" 

1
你可以使用 range 代替 maxmintoString(sapply(split(nums, cumsum(c(1, diff(nums) != 1))), function(x) ifelse(length(x) > 2, paste(range(x), collapse = "-"), x))) - d.b

0

您也可以使用cgwtools中的seqle,它是Base Rrle的扩展:

year = c(2000,2001,2002,2003, 2005, 2007,2008,2009,2010)

library(dplyr)
library(cgwtools)

seqle(year) %>%
  {paste0(.$values, "-", .$values+(.$lengths-1))} %>%
  toString() %>%
  gsub("(\\d+)[-]\\1", "\\1", .)

# [1] "2000-2003, 2005, 2007-2010"

seqle 编码了线性序列的 year 并输出了 lengthsvalues,这使我可以相当容易地将它们加在一起。 gsub2005-2005 替换为所需的 2005

> seqle(year)
Run Length Encoding
  lengths: int [1:3] 4 1 4
  values : num [1:3] 2000 2005 2007

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接