【发布时间】:2014-11-15 16:48:03
【问题描述】:
我想以这种方式合并 2 个向量:
a = c(1,2,3)
b = c(11,12,13)
merged vector : c(1,11,2,12,3,13)
我该怎么做?
【问题讨论】:
-
一些方法here
我想以这种方式合并 2 个向量:
a = c(1,2,3)
b = c(11,12,13)
merged vector : c(1,11,2,12,3,13)
我该怎么做?
【问题讨论】:
@MBo 在https://stackoverflow.com/a/58773002/2556061 上对我的问题的回答暗示了一种解决不等长度均匀交错向量的解决方案。我在这里报告它以供参考。
interleave <- function(x, y)
{
m <- length(x)
n <- length(y)
xi <- yi <- 1
len <- m + n
err <- len %/% 2
res <- vector()
for (i in 1:len)
{
err <- err - m
if (err < 0)
{
res[i] <- x[xi]
xi <- xi + 1
err <- err + len
} else
{
res[i] <- y[yi]
yi <- yi + 1
}
}
res
}
给予
interleave(1:10, 100:120)
c(100, 1, 101, 102, 2, 103, 104, 3, 105, 106, 4, 107, 108, 5, 109, 110, 111, 6, 112, 113, 7, 114, 115, 8, 116, 117, 9, 118, 119, 10, 120)
【讨论】:
@jalapic 的rbind() 回答非常好。这是一种替代方法,它创建一个新向量,然后为其分配交替值。
a <- c(1,2,3)
b <- c(11,12,13)
x <- vector(class(a), length(c(a, b)))
x[c(TRUE, FALSE)] <- a
x[c(FALSE, TRUE)] <- b
x
# [1] 1 11 2 12 3 13
还有一个显示append
c(sapply(seq_along(a), function(i) append(a[i], b[i], i)))
# [1] 1 11 2 12 3 13
【讨论】:
c(TRUE, FALSE),当用于索引时,表示以 first 开头的所有其他值。 c(TRUE, FALSE) 在向量的整个长度中被循环使用(所以在这个例子中就像说“是,不,是,不,是,不”)。另一方面,c(FALSE TRUE) 以相同的方式获取从 second 开始的所有其他值。
只是想添加一个更简单的解决方案,适用于向量长度不等并且您希望将额外数据附加到末尾的情况。
> a <- 1:3
> b <- 11:17
> c(a, b)[order(c(seq_along(a)*2 - 1, seq_along(b)*2))]
[1] 1 11 2 12 3 13 14 15 16 17
解释:
c(a, b) 创建一个包含 a 和 b 中的值的向量。seq_along(a)*2 - 1 创建第一个 length(a) 奇数的向量。seq_along(b)*2 创建第一个 length(b) 偶数的向量。order(...) 将返回两个 seq_along 向量中数字的索引,使得 x[order(x)] 是一个有序列表。由于第一个seq_along 包含偶数,第二个seq_along 包含赔率,订单将采用第一个seq_along 的第一个元素,然后是第二个seq_along 的第一个元素,然后是第二个元素首先seq_along等,将两个向量索引穿插在一起,将多余的数据留在尾部。order 向量索引c(a, b),我们将穿插a 和b。请注意,由于seq_along 在输入为NULL 时返回numeric(0),因此即使其中一个向量的长度为0,此解决方案也有效。
【讨论】:
c(a,b)[order(c(seq_along(a),seq_along(b)))] 就应该这样做。无需奇数/偶数计算。
我必须解决类似的问题,但我的向量长度不等。而且,我不想回收较短的向量,而只是附加较长向量的尾部。
@RichardScriven 的解决方案对我不起作用(尽管我可能做错了什么并且没有努力排除故障)。
这是我的解决方案:
#' Riffle-merges two vectors, possibly of different lengths
#'
#' Takes two vectors and interleaves the elements. If one vector is longer than
#' the other, it appends on the tail of the longer vector to the output vector.
#' @param a First vector
#' @param b Second vector
#' @return Interleaved vector as described above.
#' @author Matt Pettis
riffle <- function(a, b) {
len_a <- length(a)
len_b <- length(b)
len_comm <- pmin(len_a, len_b)
len_tail <- abs(len_a - len_b)
if (len_a < 1) stop("First vector has length less than 1")
if (len_b < 1) stop("Second vector has length less than 1")
riffle_common <- c(rbind(a[1:len_comm], b[1:len_comm]))
if (len_tail == 0) return(riffle_common)
if (len_a > len_b) {
return(c(riffle_common, a[(len_comm + 1):len_a]))
} else {
return(c(riffle_common, b[(len_comm + 1):len_b]))
}
}
# Try it out
riffle(1:7, 11:13)
[1] 1 11 2 12 3 13 4 5 6 7
riffle(1:3, 11:17)
[1] 1 11 2 12 3 13 14 15 16 17
HTH, 马特
【讨论】:
这将使用 rbind 工作:
c(rbind(a, b))
例如:
a = c(1,2,3)
b = c(11,12,13)
c(rbind(a,b))
#[1] 1 11 2 12 3 13
【讨论】:
length(a) 大于 lenght(b) 或 max 的长度用于索引)。
c 的副作用之一是将数据结构转换为向量。所以在这里使用c类似于as.vector(rbind(a,b))