Pegando dos vectores con combinaciones de todos los elementos de vectores

Tengo dos vectores:

vars <- c("SR", "PL") vis <- c(1,2,3) 

En base a estos vectores, me gustaría crear el siguiente vector:

 "SR.1" "SR.2" "SR.3" "PL.1" "PL.2" "PL.3" 

Con paste tengo el siguiente resultado:

 paste(vars, vis, sep=".") [1] "SR.1" "PL.2" "SR.3" 

¿Cómo puedo crear el vector que necesito?

Puede usar esto, pero puede haber una solución más simple:

 R> apply(expand.grid(vars, vis), 1, paste, collapse=".") [1] "SR.1" "PL.1" "SR.2" "PL.2" "SR.3" "PL.3" 

expand.grid devuelve un data.frame que cuando se usa con apply , apply lo convertirá en una matrix . Esto es simplemente innecesario (e ineficiente en datos grandes). outer da una matrix y también toma el argumento de la función. También será muy eficiente en datos enormes.

Usando outer :

 as.vector(outer(vars, vis, paste, sep=".")) # [1] "SR.1" "PL.1" "SR.2" "PL.2" "SR.3" "PL.3" 

Esta vieja pregunta ya tiene una respuesta aceptada. Pero como se está usando como objective duplicado, creo que vale la pena agregar una solución data.table que utiliza la función de combinación cruzada CJ() :

 library(data.table) CJ(vars, vis)[, paste(V1, V2, sep =".")] #[1] "PL.1" "PL.2" "PL.3" "SR.1" "SR.2" "SR.3" 

En caso de que el pedido original sea importante:

 CJ(vars, vis, sorted = FALSE)[, paste(V1, V2, sep =".")] #[1] "SR.1" "SR.2" "SR.3" "PL.1" "PL.2" "PL.3" 

Para mantener el orden de las cadenas solicitadas en la pregunta, puede usar estas dos modificaciones de ambos métodos:

Cambiar el orden de los vectores y combinarlos en orden inverso

 apply(expand.grid(vis, vars), 1, function(x) paste(x[2], x[1], sep=".")) [1] "SR.1" "SR.2" "SR.3" "PL.1" "PL.2" "PL.3" 

o transponer la matriz antes de convertirla en vector:

 as.vector(t(outer(vars, vis, paste, sep="."))) [1] "SR.1" "SR.2" "SR.3" "PL.1" "PL.2" "PL.3" 

Otra opción es usar sprintf en combinación con expand.grid :

 eg <- expand.grid(vis, vars) sprintf('%s.%s', eg[,2], eg[,1]) 

lo que da:

 [1] "SR.1" "SR.2" "SR.3" "PL.1" "PL.2" "PL.3" 

Explicación:

  • Con expand.grid crea todas las combinaciones de los dos vectores.
  • sprintf pega los dos vectores juntos de acuerdo con el formato especificado ( '%s.%s' ). Cada %s parte del formato se reemplaza por los elementos de los vectores.

Otra opción es usar each argumento de rep :

 paste(rep(vars, each = length(vis)), vis, sep = ".") 

Encuentro esto más sencillo que las soluciones basadas en apply o expand.grid .