Come unire 2 vettori alternando gli indici?

Vorrei unire 2 vettori in questo modo:

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

Come potrei farlo?

rbind usando rbind :

 c(rbind(a, b)) 

Per esempio:

 a = c(1,2,3) b = c(11,12,13) c(rbind(a,b)) #[1] 1 11 2 12 3 13 

La risposta rbind() di @jalapic è eccellente. Ecco un’alternativa che crea un nuovo vettore e assegna ad esso i valori alternati.

 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 

E un altro che mostra append

 c(sapply(seq_along(a), function(i) append(a[i], b[i], i))) # [1] 1 11 2 12 3 13 

Ho dovuto risolvere un problema simile, ma i miei vettori erano di lunghezza disuguale. E, non volevo riciclare il vettore più corto, ma semplicemente aggiungere la coda del vettore più lungo.

E la soluzione per @RichardScriven non ha funzionato per me (anche se ho potuto fare qualcosa di sbagliato e non ho provato a risolvere il problema).

Ecco la mia soluzione:

 #' 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, Matt

Volevo solo aggiungere una soluzione più semplice che funzioni quando i vettori sono di lunghezza disuguale e vuoi aggiungere i dati extra alla fine.

 > 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 

Spiegazione:

  • c(a, b) crea un vettore dei valori in a e b .
  • seq_along(a)*2 - 1 crea un vettore della prima length(a) numeri dispari.
  • seq_along(b)*2 crea un vettore della prima length(b) numeri pari.
  • order(...) restituirà gli indici dei numeri nei due vettori seq_along tali che x[order(x)] è una lista ordinata. Poiché il primo seq_along contiene i numeri pari e il secondo seq_along ha le probabilità, l’ordine prenderà il primo elemento dal primo seq_along , quindi i primi elementi del secondo seq_along , quindi il secondo elemento dal primo seq_along , ecc. Che interspazia i due indici vettoriali e lasciando i dati extra alla coda.
  • Indicando c(a, b) usando il vettore order , interspondereremo a e b .

Come nota, poiché seq_along restituisce numeric(0) quando l’input è NULL questa soluzione funziona anche se uno dei vettori è di lunghezza 0 .