2012-11-28 15 views
6

Sto cercando di capire perché la funzione rbind non funziona come previsto quando si uniscono data.frames senza nomi. Ecco il mio test:rbind data.frames senza nomi

test <- data.frame(
      id=rep(c("a","b"),each=3), 
      time=rep(1:3,2), 
      black=1:6, 
      white=1:6, 
      stringsAsFactors=FALSE 
      ) 

# take some subsets with different names 
pt1 <- test[,c(1,2,3)] 
pt2 <- test[,c(1,2,4)] 

# method 1 - rename to same names - works 
names(pt2) <- names(pt1) 
rbind(pt1,pt2) 

# method 2 - works - even with duplicate names 
names(pt1) <- letters[c(1,1,1)] 
names(pt2) <- letters[c(1,1,1)] 
rbind(pt1,pt2) 

# method 3 - works - with a vector of NA's as names 
names(pt1) <- rep(NA,ncol(pt1)) 
names(pt2) <- rep(NA,ncol(pt2)) 
rbind(pt1,pt2) 

# method 4 - but... does not work without names at all? 
pt1 <- unname(pt1) 
pt2 <- unname(pt2) 
rbind(pt1,pt2) 

Questo sembra un po 'strano per me. Mi manca una buona ragione per cui questo non dovrebbe funzionare fuori dalla scatola?

modifica per ulteriori informazioni

Utilizzando @ suggerimento di JoshO'Brien a debug, posso identificare l'errore come si verifica durante questa parte if dichiarazione della funzione rbind.data.frame

if (is.null(pi) || is.na(jj <- pi[[j]])) 

(versione on line del codice: http://svn.r-project.org/R/trunk/src/library/base/R/dataframe.R a partire da: "### Ecco i metodi per rbind e cbind.")

Dall'esecuzione del programma, il valore di pi non sembra essere stato impostato a questo punto, quindi il programma tenta di indicizzare la costante incorporata pi come pi[[3]] e gli errori.

Da quello che posso capire, il pi oggetto interno non sembra essere impostato a causa di questa linea precedente in cui clabs è stato inizializzato come NULL:

if (is.null(clabs)) clabs <- names(xi) else { #pi gets set here 

Sono in un groviglio cercando di capire questo fuori, ma si aggiornerà quando si unirà.

+3

Dai un'occhiata al codice di 'rbind.data.frame' ** più ** di cui è interessato il controllo e la corrispondenza dei nomi di colonne e righe. Si potrebbe fare 'debug (rbind.data.frame)' e quindi passare attraverso il metodo 4 per determinare esattamente dove viene generato l'errore. –

+0

@ JoshO'Brien - sono stati aggiornati per fornire ulteriori informazioni. Non sono così bravo a interpretare il codice e ci sto lavorando, ma forse sarà ovvio per qualcun altro. – thelatemail

risposta

5

Perché unname() & l'assegnazione esplicita di NA come intestazioni di colonna non sono azioni identiche. Quando i nomi delle colonne sono tutti NA, è possibile un rbind(). Poiché rbind() prende i nomi/i nomi dei dati del frame dei dati, i risultati non corrispondono a & e pertanto rbind() non riesce.

Ecco il codice per aiutare a vedere quello che voglio dire:

> c1 <- c(1,2,3) 
> c2 <- c('A','B','C') 
> df1 <- data.frame(c1,c2) 
> df1 
    c1 c2 
1 1 A 
2 2 B 
3 3 C 
> df2 <- data.frame(c1,c2) # df1 & df2 are identical 
> 
> #Let's perform unname on one data frame & 
> #replacement with NA on the other 
> 
> unname(df1) 
    NA NA 
1 1 A 
2 2 B 
3 3 C 
> tem1 <- names(unname(df1)) 
> tem1 
NULL 
> 
> #Please note above that the column headers though showing as NA are null 
> 
> names(df2) <- rep(NA,ncol(df2)) 
> df2 
    NA NA 
1 1 A 
2 2 B 
3 3 C 
> tem2 <- names(df2) 
> tem2 
[1] NA NA 
> 
> #Though unname(df1) & df2 look identical, they aren't 
> #Also note difference in tem1 & tem2 
> 
> identical(unname(df1),df2) 
[1] FALSE 
> 

Spero che questo aiuta. I nomi appaiono come NA ciascuno, ma le due operazioni sono diverse. Quindi, 2 frame di dati con le loro intestazioni di colonna sostituite su NA possono essere "rbound" ma non possono essere 2 frame di dati senza intestazioni di colonna (ottenuti utilizzando unname()).

+2

Questa è una buona informazione e ho + 1. Mentre posso vedere che i datafram di 'NA' e' unname' hanno nomi 'diversi()', penso che R dovrebbe essere in grado di 'rbind' senza nome' data.frames' se può gestire 'names()' che sono tutti 'NA's. – thelatemail

Problemi correlati