unir - ¿Cómo fusionar 2 vectores de índices alternos?
unir dos vectores en r (4)
Me gustaría fusionar 2 vectores de esta manera:
a = c(1,2,3)
b = c(11,12,13)
merged vector : c(1,11,2,12,3,13)
¿Cómo podría hacerlo?
Esto funcionará usando rbind
:
c(rbind(a, b))
Por ejemplo:
a = c(1,2,3)
b = c(11,12,13)
c(rbind(a,b))
#[1] 1 11 2 12 3 13
La respuesta de rbind()
por @jalapic es excelente. Aquí hay una alternativa que crea un nuevo vector y luego le asigna los valores alternos.
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
Y una más que se muestra append
c(sapply(seq_along(a), function(i) append(a[i], b[i], i)))
# [1] 1 11 2 12 3 13
Solo quería agregar una solución más simple que funcione cuando los vectores tienen una longitud desigual y desea agregar los datos adicionales al final.
> 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
Explicación:
-
c(a, b)
crea un vector de los valores ena
yb
. -
seq_along(a)*2 - 1
crea un vector de la primeralength(a)
números impares. -
seq_along(b)*2
crea un vector de los números pares de la primeralength(b)
. -
order(...)
devolverá los índices de los números en los dos vectoresseq_along
modo quex[order(x)]
es una lista ordenada. Dado que el primerseq_along
contiene los números pares y el segundoseq_along
tiene las probabilidades, el orden tomará el primer elemento del primerseq_along
, luego los primeros elementos del segundoseq_along
, luego el segundo elemento del primerseq_along
, etc. Índices vectoriales y dejando los datos extra en la cola. - Al indexar
c(a, b)
usando el vector deorder
, intercalaremosa
yb
.
Como nota, dado que seq_along
devuelve numeric(0)
cuando la entrada es NULL
esta solución funciona incluso si uno de los vectores es de longitud 0
.
Tuve que resolver un problema similar, pero mis vectores tenían una longitud desigual. Y, no quería reciclar el vector más corto, sino simplemente añadir la cola del vector más largo.
Y la solución para @RichardScriven no funcionó para mí (aunque puede que haya hecho algo mal y no haya tratado de solucionarlo).
Aquí está mi solución:
#'' 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