我试图为两个任意长度的向量编写一个interleave()
函数。
对于等长向量, 我在internet中找到了:
.interleave <- function(vec1, vec2) {
# cuts away longer
res <- rbind(vec1, vec2)
attributes(res) <- NULL
res
}
# c(rbind(vec1, vec2)) is shorter code, but
# is 3x slower according to the blog in the link
所以我想,对于任意长度,我先测量长度,然后附加其余的较长向量。
interleave <- function(vec1, vec2) {
vec1_len <- length(vec1)
vec2_len <- length(vec2)
min_len <- min(vec1_len, vec2_len)
if (vec1_len == vec2_len) {
.interleave(vec1, vec2)
} else {
c(.interleave(vec1[1:min_len], vec2[1:min_len]),
if (vec1_len > vec2_len) {
vec1[min_len+1:vec1_len]
} else {
vec2[min_len+1:vec2_len]
})
}
} # strangely 3 NA's at end if unequal length
但现在出现了奇怪的事情:
interleave(c(1, 2, 3), c(4, 5, 6, 7, 8, 9))
## [1] 1 4 2 5 3 6 7 8 9 NA NA NA
interleave(c(1, 2, 3), c(4, 5, 6))
## [1] 1 4 2 5 3 6
interleave(c(1, 2, 3), c(4, 5))
## [1] 1 4 2 5 3 NA NA
interleave(c(1, 2, 3), c(4, 5, 6, 7, 8, 9, 10, 11))
## [1] 1 4 2 5 3 6 7 8 9 10 11 NA NA NA
interleave(c(1, 2, 3, 4, 5, 6), c( 7, 8, 9, 10, 11))
## [1] 1 7 2 8 3 9 4 10 5 11 6 NA NA NA NA NA
NA
来自何处?
备注:我看到了这样的模式,即附加的NA
数量
是较短向量中的元素数量...
如何生成没有NA
的版本?
解决方案
对不起,我自己发现了。 问题是剩余向量的子集。 我忘记了一些寄生物。
interleave <- function(vec1, vec2) {
vec1_len <- length(vec1)
vec2_len <- length(vec2)
min_len <- min(vec1_len, vec2_len)
if (vec1_len == vec2_len) {
.interleave(vec1, vec2)
} else {
c(.interleave(vec1[1:min_len], vec2[1:min_len]),
if (vec1_len > vec2_len) {
vec1[(min_len+1):vec1_len] # parantheses!
} else {
vec2[(min_len+1):vec2_len] # parantheses!
})
}
} # no NA's any more!
稍短
interleave <- function(vec1, vec2) {
vec1_len <- length(vec1)
vec2_len <- length(vec2)
min_len <- min(vec1_len, vec2_len)
if (vec1_len == vec2_len) {
.interleave(vec1, vec2)
} else {
c(.interleave(vec1[1:min_len], vec2[1:min_len]),
if (vec1_len > vec2_len) {
vec1[(min_len+1):vec1_len]
} else {
vec2[(min_len+1):vec2_len]
})
}
}
答案 0 :(得分:0)
一般功能:
interleave <- function(...) {
l <- list(...)
len <- max(lengths(l))
l <- lapply(l, function(x) `length<-`(x, len))
res <- na.omit(c(do.call(rbind, l)))
attributes(res) <- NULL
res
}
interleave(1:9, seq(10,40,10), seq(100,500,100))
#[1] 1 10 100 2 20 200 3 30 300 4 40 400 5 500 6 7 8 9
interleave <- function(...) {
l <- list(...)
idx <- order(unlist(lapply(l, function(x) seq_along(x))))
unlist(l)[idx]
}