使用以下代码将数字向量表示为一组字符:

时间:2018-04-01 16:52:31

标签: r sequence

在R中,您可以使用:定义任意整数序列,例如

a = c(1:3, 12:14)
print(a)
## 1 2 3 12 13 14

我正在寻找一种方法来进行逆操作,例如给定一个整数向量我想生成一个字符(或字符向量),它使用:将整数序列折叠成等价表达式,例如

some_function (a)
## "1:3" "12:14"

如果可以检测到步幅,则奖励,例如c(1, 3, 5)变为"1:2:5"或类似的东西。

动机:根据一些数据操作在R中生成一个整数序列,以识别数据库行选择,并以正确的格式将该序列的最简洁表示传递给外部程序。

3 个答案:

答案 0 :(得分:1)

啊,书呆子天堂。这是第一枪。您甚至可以将其用于R中的编码。

需要测试;代码总是打印出来。

encode_ranges <- function (x) {
  rle_diff <- list(
    start = x[1],
    rled   = rle(diff(x))
  )

  class(rle_diff) <- "rle_diff"
  rle_diff
}

decode_ranges <- function (x) {
  stopifnot(inherits(x, "rle_diff"))
  cumsum(c(x$start, inverse.rle(x$rled)))
}

format.rle_diff <- function (x, ...) {
  stopifnot(inherits(x, "rle_diff"))
  output <- character(length(x$rled$values))

  start <- x$start
  for (j in seq_along(x$rled$values)) {
    stride <- x$rled$values[j]
    len    <- x$rled$lengths[j]
    if (len == 1L) {
      start <- end + stride
      next
    }
    end       <- start + stride * x$rled$lengths[j]
    output[j] <- paste(start, end, stride, sep = ":")
  }

  output <- output[nchar(output) > 0]
  paste(output, collapse = ", ")
}

print.rle_diff <- function (x, ...) cat(format(x, ...))

encode_ranges(c(1:3, 12:14))
encode_ranges(c(1, 3, 5, 8:10, 14, 17, 20))

答案 1 :(得分:1)

我们可以考虑差异的rle并将range粘贴在一起,同时考虑序列距离。

fun=function(s){
  m=c(0,diff(s))
  b=rle(m)
  b$values[b$lengths==1&b$values!=1]=0
  l=cumsum(!inverse.rle(b))
  d=function(x)paste0(range(x[,1]),
                      collapse = paste0(":",unique(x[-1,-1]),":"))
  f=c(by(cbind(s,m),l,d))
  sub("::.*","",sub(":1:",":",f))
}   

fun(c(1,1:3,12:14,c(1,3,5)))
      1       2       3       4 
    "1"   "1:3" "12:14" "1:2:5" 
fun(c(1, 3, 5, 8:10, 14, 17, 20))
        1         2         3 
  "1:2:5"    "8:10" "14:3:20" 

fun(1)
  1 
"1" 

答案 2 :(得分:0)

我们使用'4 + 5'diff创建分组变量,然后在功能组上使用cumsum paste个值

range

对于第二种情况

f1 <- function(vec) {
  unname(tapply(vec, cumsum(c(TRUE, diff(vec) != 1)), 
       FUN = function(x) paste(range(x), collapse=":")))
  }

f1(a) 
#[1] "1:3"   "12:14"