2013-04-22 19 views
40

Ho due vettori:Incollare due vettori con combinazioni di elementi tutti i vettori

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

Sulla base di questi vettori vorrei creare il seguente vettore:

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

Con paste ho la seguente risultato:

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

Come posso creare il vettore di cui ho bisogno?

risposta

47

è possibile utilizzare questo, ma ci può essere una soluzione più semplice:

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

expand.grid dà indietro un data.frame, che quando viene utilizzato con apply, apply sarà convertirlo in un matrix. Questo è solo inutile (e inefficiente su dati di grandi dimensioni). outer fornisce un matrix e accetta anche argomenti di funzione. Sarà molto efficiente anche su enormi dati.

Utilizzando outer:

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

Per mantenere l'ordine delle corde richiesti nella domanda, è possibile utilizzare queste due modifiche di entrambi i metodi:

Modifica ordine di vettori e combinare in ordine 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 trasporre la matrice prima della conversione a vettoriale:

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

Un'altra opzione utilizzando sprintf in combinazione con expand.grid:

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

che dà:

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

Spiegazione:

  • Con expand.grid di creare tutte le combinazioni dei due vettori.
  • sprintf incolla i due vettori insieme in base al formato specificato ('%s.%s'). Ogni parte %s del formato viene sostituita dagli elementi dei vettori.
+1

I pensa che questa sia la soluzione più elegante di tutte le proposte! –

5

Questa vecchia domanda ha già una risposta accettata.Ma come è usato come bersaglio vittima, credo che valga la pena di aggiungere una soluzione data.table che utilizza il cross join funzione CJ():

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

Nel caso in cui l'ordine originale è importante:

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