Подтвердить что ты не робот

Как слить 2 вектора чередующихся индексов?

Я хотел бы объединить 2 вектора следующим образом:

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

Как я могу это сделать?

4b9b3361

Ответ 1

Это будет работать с помощью 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 

Ответ 2

Ответ rbind() на @jalapic отличный. Здесь альтернатива, которая создает новый вектор, затем присваивает ему переменные значения.

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

Ответ 3

Просто хотел добавить более простое решение, которое работает, когда векторы имеют неравную длину, и вы хотите добавить дополнительные данные в конец.

> 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 и т.д., вставляя два векторных индекса и оставляя дополнительные данные в хвосте.
  • Индексируя c(a, b) с помощью вектора order, мы будем пересекать a и b.

В качестве примечания, поскольку seq_along возвращает numeric(0), когда вход NULL, это решение работает, даже если один из векторов - длина 0.

Ответ 4

Мне пришлось решить подобную проблему, но мои векторы имели неравную длину. И я не хотел перерабатывать более короткий вектор, но просто добавляю хвост более длинного вектора.

И решение для @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

НТН, Matt