在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中生成一个整数序列,以识别数据库行选择,并以正确的格式将该序列的最简洁表示传递给外部程序。
答案 0 :(得分:1)
需要测试;代码总是打印出来。
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"