2013-02-10 12 views
9

Ho una lista di oggetti data.frame che vorrei aggiungere una riga l'una all'altra, ovvero merge(..., all=T). Tuttavia, merge sembra rimuovere i nomi delle righe che devo mantenere intatti. Qualche idea? Esempio:rbind due data.frame che conserva l'ordine delle righe e i nomi delle righe

x = data.frame(a=1:2, b=2:3, c=3:4, d=4:5, row.names=c("row_1", "another_row1")) 
y = data.frame(a=c(10,20), b=c(20,30), c=c(30,40), row.names=c("row_2", "another_row2")) 
> merge(x, y, all=T, sort=F) 
    a b c d 
    1 1 2 3 4 
    2 2 3 4 5 
    3 10 20 30 NA 
    4 20 30 40 NA 
+0

può essere z <- unione (x, y, tutto = T, sort = F); rownames (z) <- c (rownames (x), rownames (y)) –

+3

Se ho capito bene, si vuole 'frame di dati rbind' di un diverso numero di colonne insieme. [Questa domanda] (http://stackoverflow.com/questions/3402371/rbind-different-number-of-columns) potrebbe essere utile a voi, in particolare, 'rbind.fill' dal pacchetto' plyr'. –

+0

@Arun [risposta di Ananda Mahto] (http://stackoverflow.com/a/14799551/697568) si prende cura di questo. –

risposta

14

Poiché si sa che non sono in realtà la fusione, ma solo rbind-ing, forse qualcosa di simile a questo funzionerà. Fa uso di rbind.fill da "plyr". Per usarlo, specificare una list dei data.frame s che si desidera rbind.

RBIND <- function(datalist) { 
    require(plyr) 
    temp <- rbind.fill(datalist) 
    rownames(temp) <- unlist(lapply(datalist, row.names)) 
    temp 
} 
RBIND(list(x, y)) 
#    a b c d 
# row_1   1 2 3 4 
# another_row1 2 3 4 5 
# row_2  10 20 30 NA 
# another_row2 20 30 40 NA 
11

Un modo è utilizzare row.names in unione in modo da ottenere come colonna aggiuntiva.

> merge(x, y, by=c("row.names", "a","b","c"), all.x=T, all.y=T, sort=F) 

#  Row.names a b c d 
# 1  row_1 1 2 3 4 
# 2 another_row1 2 3 4 5 
# 3  row_2 10 20 30 NA 
# 4 another_row2 20 30 40 NA 

Edit: Osservando la funzione merge con getS3method('merge', 'data.frame'), il row.names sono chiaramente impostato su NULL (si tratta di un codice piuttosto lunga, quindi non mi incollare qui).

# Commenting 
# Lines 63 and 64 
row.names(x) <- NULL 
row.names(y) <- NULL 

# and 
# Line 141 (thanks Ananda for pointing out) 
attr(res, "row.names") <- .set_row_names(nrow(res)) 

e la creazione di una nuova funzione, diciamo, MERGE, funziona come il PO intende per questo esempio. Solo una sperimentazione.

+0

+1. Mi dimentico sempre di essere in grado di unire il ' "row.names"' – A5C1D2H2I1M1N2O1R2T1

+0

Per quanto riguarda la tua modifica, ho anche dovuto rimuovere la linea 141 ('attr (res " row.names"<) - .set_row_names (nRow (res)) '). Ho messo un gist [qui] (https://gist.github.com/mrdwab/4750113) che può essere caricato ed eseguito con 'library (devtools); source_gist (4750113); MERGE (x, y, all = TRUE) ', almeno in parte convalidando la tua sperimentazione. – A5C1D2H2I1M1N2O1R2T1

+0

Immaginiamo di avere un terzo df, 'z <- data.frame (a = c (11, 21), b = c (22, 32), d = c (33, 43), row.names = c ("row_3", "another_row3")) '. Come possiamo ottenere un 'unione' normale per lavorare (magari con 'Riduci ', o anche manualmente)? 'MERGE' funziona come previsto con' Riduci (funzione (x, y) MERGE (x, y, all = TRUE, sort = FALSE), lista (x, y, z)) '(più o meno - l'ordine delle colonne cambia), e 'RBIND (list (x, y, z))' fa anche il trucco. Ma non riesco a capire una soluzione di fusione di base non adulterata qui. Qualche idea? – A5C1D2H2I1M1N2O1R2T1

Problemi correlati