如何合并2个向量交替索引?

我想这样合并两个向量:

a = c(1,2,3)
b = c(11,12,13)
merged vector : c(1,11,2,12,3,13)

我怎么能这么做呢?

22668 次浏览

这将使用 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

解释

这是因为 R 在 列-主要顺序中存储数组。

当你把这两个向量 rbind(),你会得到:

rbind_result <- rbind(a, b)
rbind_result
#   [,1] [,2] [,3]
# a    1    2    3
# b   11   12   13

然后 c()强迫 rbind_result进入一个列向量:

merged <- c(rbind_result)
merged
# [1] 1 11 2 12 3 13

@ 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

我必须解决一个类似的问题,但是我的向量长度不等。我不想重复使用较短的向量,只是附加较长向量的尾部。

而@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, 马特

只是想添加一个简单的解决方案,当向量长度不等时,你想把额外的数据附加到结尾。

> 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)创建 ab中值的向量。
  • 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),我们将散布 ab

值得注意的是,当输入为 NULL时,由于 seq_along返回 numeric(0),因此即使其中一个向量的长度为 0,该解决方案也能正常工作。

@ 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)