combinando due frame di dati di diverse lunghezze

Ho due frame di dati.
Il primo è di una sola colonna e 10 righe.
Il secondo è di 3 colonne e 50 righe.

Quando provo a combinare questo usando cbind , dà questo errore:

Errore in data.frame (…, check.names = FALSE):

Qualcuno può suggerire un’altra funzione per farlo?
PS Ho provato anche questo usando gli elenchi, ma dà lo stesso errore.

Il frame di dati composto da 3 colonne dovrebbe essere le prime 3 colonne in un file CSV, mentre il frame di dati con una colonna dovrebbe essere la quarta colonna in quel file, quando scrivo con la funzione write.table . Le prime 3 colonne hanno 50 righe e la quarta colonna dovrebbe occupare le prime 10 righe.

Nel pacchetto plyr esiste una funzione rbind.fill che unirà data.frames e introdurrà NA per le celle vuote:

 library(plyr) combined <- rbind.fill(mtcars[c("mpg", "wt")], mtcars[c("wt", "cyl")]) combined[25:40, ] mpg wt cyl 25 19.2 3.845 NA 26 27.3 1.935 NA 27 26.0 2.140 NA 28 30.4 1.513 NA 29 15.8 3.170 NA 30 19.7 2.770 NA 31 15.0 3.570 NA 32 21.4 2.780 NA 33 NA 2.620 6 34 NA 2.875 6 35 NA 2.320 4 

Non mi è chiaro affatto in cosa consista l’OP, visti i commenti di follow-up. È ansible che stiano davvero cercando un modo per scrivere i dati su file.

Ma supponiamo che stiamo davvero cbind un modo per cbind più frame di dati di lunghezza diversa.

cbind chiamerà infine data.frame , i cui file di aiuto dicono:

Gli oggetti passati a data.frame dovrebbero avere lo stesso numero di righe, ma i vettori atomici, i fattori ei vettori di caratteri protetti da I verranno riciclati un numero intero di volte, se necessario (compresi da R 2.9.0, elementi di argomenti di lista).

quindi nell’esempio reale dell’OP, non dovrebbe esserci un errore, in quanto R dovrebbe riciclare i vettori più brevi per essere di lunghezza 50. Infatti, quando eseguo quanto segue:

 set.seed(1) a <- runif(50) b <- 1:50 c <- rep(LETTERS[1:5],length.out = 50) dat1 <- data.frame(a,b,c) dat2 <- data.frame(d = runif(10),e = runif(10)) cbind(dat1,dat2) 

Non ottengo errori e il frame dati più breve viene riciclato come previsto. Tuttavia, quando eseguo questo:

 set.seed(1) a <- runif(50) b <- 1:50 c <- rep(LETTERS[1:5],length.out = 50) dat1 <- data.frame(a,b,c) dat2 <- data.frame(d = runif(9), e = runif(9)) cbind(dat1,dat2) 

Ottengo il seguente errore:

 Error in data.frame(..., check.names = FALSE) : arguments imply differing number of rows: 50, 9 

Ma la cosa meravigliosa di R è che puoi farcela quasi tutto ciò che vuoi, anche se non dovresti. Ad esempio, ecco una semplice funzione che cbind i frame di dati di lunghezza non uniforms e li cbind automaticamente con quelli di NA :

 cbindPad <- function(...){ args <- list(...) n <- sapply(args,nrow) mx <- max(n) pad <- function(x, mx){ if (nrow(x) < mx){ nms <- colnames(x) padTemp <- matrix(NA, mx - nrow(x), ncol(x)) colnames(padTemp) <- nms if (ncol(x)==0) { return(padTemp) } else { return(rbind(x,padTemp)) } } else{ return(x) } } rs <- lapply(args,pad,mx) return(do.call(cbind,rs)) } 

che può essere usato in questo modo:

 set.seed(1) a <- runif(50) b <- 1:50 c <- rep(LETTERS[1:5],length.out = 50) dat1 <- data.frame(a,b,c) dat2 <- data.frame(d = runif(10),e = runif(10)) dat3 <- data.frame(d = runif(9), e = runif(9)) cbindPad(dat1,dat2,dat3) 

Non garantisco che questa funzione funzioni in tutti i casi; è solo un esempio.

MODIFICARE

Se l'objective principale è creare un file csv o di testo, tutto ciò che devi fare è modificare la funzione in pad usando "" anziché NA e poi fare qualcosa del genere:

 dat <- cbindPad(dat1,dat2,dat3) rs <- as.data.frame(apply(dat,1,function(x){paste(as.character(x),collapse=",")})) 

e quindi usa write.table su rs .

Facendo riferimento alla risposta di Andrie, suggerendo di usare plyr::rbind.fill() : Combinato con t() hai qualcosa come cbind.fill() (che non fa parte di plyr ) che costruirà il tuo frame di dati con considerazione del caso identico numeri.

La mia idea è di ottenere il massimo numero di righe di tutti i data.frames e successivamente di aggiungere una matrice vuota a ogni data.frame se necessario. Questo metodo non richiede pacchetti aggiuntivi, viene utilizzata solo la base. Il codice sembra seguire:

 list.df <- list(data.frame(a = 1:10), data.frame(a = 1:5), data.frame(a = 1:3)) max.rows <- max(unlist(lapply(list.df, nrow), use.names = F)) list.df <- lapply(list.df, function(x) { na.count <- max.rows - nrow(x) if (na.count > 0L) { na.dm <- matrix(NA, na.count, ncol(x)) colnames(na.dm) <- colnames(x) rbind(x, na.dm) } else { x } }) do.call(cbind, list.df) # aaa # 1 1 1 1 # 2 2 2 2 # 3 3 3 3 # 4 4 4 NA # 5 5 5 NA # 6 6 NA NA # 7 7 NA NA # 8 8 NA NA # 9 9 NA NA # 10 10 NA NA 

Spero che questo funzioni per te!

È ansible utilizzare la library(qpcR) per combinare due matrici con dimensioni non uguali.

 resultant_matrix <- qpcR:::cbind.na(matrix1, matrix2) 

NOTA: - La matrice risultante sarà della dimensione della matrice2.

In realtà non ho un errore con questo.

 a <- as.data.frame(matrix(c(sample(letters,50, replace=T),runif(100)), nrow=50)) b <- sample(letters,10, replace=T) c <- cbind(a,b) 

Ho usato le lettere in caso di iscrizione a tutti i numeri avevano diverse funzionalità (che non ha). Il tuo 'primo frame dei dati', che in realtà è solo un vettore ', è appena ripetuto 5 volte in quella quarta colonna ...

Ma tutti i commenti dei guru alla domanda sono ancora pertinenti 🙂

Penso di aver trovato una soluzione abbastanza breve .. Spero che aiuti qualcuno.

 cbind.na<-function(df1, df2){ #Collect all unique rownames total.rownames<-union(x = rownames(x = df1),y = rownames(x=df2)) #Create a new dataframe with rownames df<-data.frame(row.names = total.rownames) #Get absent rownames for both of the dataframe absent.names.1<-setdiff(x = rownames(df1),y = rownames(df)) absent.names.2<-setdiff(x = rownames(df2),y = rownames(df)) #Fill absents with NAs df1.fixed<-data.frame(row.names = absent.names.1,matrix(data = NA,nrow = length(absent.names.1),ncol=ncol(df1))) colnames(df1.fixed)<-colnames(df1) df1<-rbind(df1,df1.fixed) df2.fixed<-data.frame(row.names = absent.names.2,matrix(data = NA,nrow = length(absent.names.2),ncol=ncol(df2))) colnames(df2.fixed)<-colnames(df2) df2<-rbind(df2,df2.fixed) #Finally cbind into new dataframe df<-cbind(df,df1[rownames(df),],df2[rownames(df),]) return(df) } 

Solo i miei 2 centesimi. Questo codice combina due matrici o data.frames in una sola. Se una struttura dati ha un numero inferiore di righe, le righe mancanti verranno aggiunte con valori NA.

 combine.df <- function(x, y) { rows.x <- nrow(x) rows.y <- nrow(y) if (rows.x > rows.y) { diff <- rows.x - rows.y df.na <- matrix(NA, diff, ncol(y)) colnames(df.na) <- colnames(y) cbind(x, rbind(y, df.na)) } else { diff <- rows.y - rows.x df.na <- matrix(NA, diff, ncol(x)) colnames(df.na) <- colnames(x) cbind(rbind(x, df.na), y) } } df1 <- data.frame(1:10, row.names = 1:10) df2 <- data.frame(1:5, row.names = 10:14) combine.df(df1, df2) 

Ho avuto un problema simile, ho abbinato le voci in una particolare colonna di due set di dati e cbind solo se corrispondeva. Per due set di dati, data1 e data2, sto aggiungendo una colonna in data1 da data2 dopo aver confrontato la prima colonna di entrambi.

 for(i in 1:nrow(data1){ for( j in 1:nrow(data2){ if (data1[i,1]==data2[j,1]) data1[i,3]<- data2[j,2] } }