2013-05-21 23 views
26

ho raccogliere dati da 4 DF e vorrebbero unirle per rownames. Sto cercando un modo efficace per farlo. Questa è una versione semplificata dei dati che ho.Unione di più di 2 dataframes in R da rownames

df1   <- data.frame(N= sample(seq(9, 27, 0.5), 40, replace= T), 
          P= sample(seq(0.3, 4, 0.1), 40, replace= T), 
          C= sample(seq(400, 500, 1), 40, replace= T)) 
df2   <- data.frame(origin= sample(c("A", "B", "C", "D", "E"), 40, 
              replace= T), 
          foo1= sample(c(T, F), 40, replace= T), 
          X= sample(seq(145600, 148300, 100), 40, replace= T), 
          Y= sample(seq(349800, 398600, 100), 40, replace= T)) 
df3   <- matrix(sample(seq(0, 1, 0.01), 40), 40, 100) 
df4   <- matrix(sample(seq(0, 1, 0.01), 40), 40, 100) 
rownames(df1) <- paste("P", sprintf("%02d", c(1:40)), sep= "") 
rownames(df2) <- rownames(df1) 
rownames(df3) <- rownames(df1) 
rownames(df4) <- rownames(df1) 

Questo è quello che normalmente fare:

# merge df1 and df2 
dat   <- merge(df1, df2, by= "row.names", all.x= F, all.y= F) #merge 
rownames(dat) <- dat$Row.names #reset rownames 
dat$Row.names <- NULL #remove added rownames col 

# merge dat and df3 
dat   <- merge(dat, df3, by= "row.names", all.x= F, all.y= F) #merge 
rownames(dat) <- dat$Row.names #reset rownames 
dat$Row.names <- NULL #remove added rownames col 

# merge dat and df4 
dat   <- merge(dat, df4, by= "row.names", all.x= F, all.y= F) #merge 
rownames(dat) <- dat$Row.names #reset rownames 
dat$Row.names <- NULL #remove added rownames col 

Come si può vedere, questo richiede un sacco di codice. La mia domanda è se lo stesso risultato può essere raggiunto con mezzi più semplici. Ho provato (senza successo): AGGIORNAMENTO: funziona ora!

MyMerge  <- function(x, y){ 
    df   <- merge(x, y, by= "row.names", all.x= F, all.y= F) 
    rownames(df) <- df$Row.names 
    df$Row.names <- NULL 
    return(df) 
} 
dat   <- Reduce(MyMerge, list(df1, df2, df3, df4)) 

Grazie in anticipo per qualsiasi suggerimento

+1

Che cosa esattamente cosa si intende per 'senza Success'? si prega di essere più specifico, contenere errori. ancora meglio, creare un esempio riproducibile. –

+0

1.) Se i nomi di fila sono sono così importanti per la vostra struc dati certo, che ti unisci da quelli, perché non passi semplicemente a 'data.frame' una vera colonna per questo? Il che ti risparmia gran parte della codifica. 2.) Anche se li mantieni puoi risparmiare un sacco di codice, vedi 'unire' parametri' by.x' e 'by.y' 3.) La rimozione di una colonna da un data.frame può essere ottenuta con' df $ Row.Names <- NULL' 4.) L'approccio 'Reduce' dovrebbe funzionare, mi sto chiedendo anche perché questo fallirebbe. – Beasterfield

+0

Ho incluso alcuni dati di esempio. Ho anche scoperto che l'approccio suggerito con funziona dopo tutto. Il problema era che volevo unire una singola colonna da un df, rimuovendo così le informazioni sui giocatori. – HDR

risposta

4

tre righe di codice vi darà esattamente lo stesso risultato:

dat2 <- cbind(df1, df2, df3, df4) 
colnames(dat2)[-(1:7)] <- paste(paste('V', rep(1:100, 2),sep = ''), 
          rep(c('x', 'y'), each = 100), sep = c('.')) 
all.equal(dat,dat2)  

Ah capisco, ora capisco perché si sta entrando così tanto dolore. Usare il vecchio ciclo for fa sicuramente il trucco. Forse ci sono anche soluzioni più intelligenti

rn <- rownames(df1) 
l <- list(df1, df2, df3, df4) 
dat <- l[[1]] 
for(i in 2:length(l)) { 
    dat <- merge(dat, l[[i]], by= "row.names", all.x= F, all.y= F) [,-1] 
    rownames(dat) <- rn 
} 
+0

Ciao, grazie per la tua risposta. Vedo come funziona. Tuttavia, e ammetto di non averlo chiarito nei miei dati di esempio, voglio che funzioni anche quando i 'rownames' sono dissimili. Quindi nell'esempio i rownames sono uguali, ma l'elaborazione dovrebbe ancora funzionare quando le righe vengono mescolate, o se ad es. 'df2' ha più o meno righe. Ecco perché ho optato per l'unione. – HDR

33

join_all da plyr probabilmente fare quello che vuoi. Ma tutti devono essere frame di dati e le rownames vengono aggiunti come una colonna

require(plyr) 

df3 <- data.frame(df3) 
df4 <- data.frame(df4) 

df1$rn <- rownames(df1) 
df2$rn <- rownames(df2) 
df3$rn <- rownames(df3) 
df4$rn <- rownames(df4) 

df <- join_all(list(df1,df2,df3,df4), by = 'rn', type = 'full') 

type argomento dovrebbe aiutare anche se le rownames variano e non corrispondono Se non si desidera che i rownames:

df$rn <- NULL 
9

Modifica la tua funzione, ho trovato la funzione che ti permette di unire più frame di dati con una specifica chiave di colonna (nome della colonna). La cornice di dati come risultato include tutte le variabili dei telai dati uniti (se vuoi tenere solo le variabili comuni (esclusi NA, uso: all.x= FALSE, all.y= FALSE)

MyMerge <- function(x, y){ 
    df <- merge(x, y, by= "name of the common column", all.x= TRUE, all.y= TRUE) 
    return(df) 
} 
new.df <- Reduce(MyMerge, list(df1, df2, df3, df4)) 
+1

Funzione piacevole, c'è comunque questa funzione può rinominare i nomi di colonna e dare nomi di colonne diff a nomi di colonne comuni? – Chirag

+0

Dopo aver unito i due frame di dati, di solito utilizzo la funzione "fix()" che consente di modificare il database, quindi è anche possibile rinominare le colonne. –

3

ho cercato per la stessa funzione Dopo aver provato un paio. . delle opzioni qui e altri altrove Il metodo più semplice per me era:

cbind.data.frame (df1, DF2, DF3, DF4 ....)

+0

Funzionerà solo se le tue file sono nello stesso ordine in ogni frame di dati. – Matt

Problemi correlati