combinando dois frameworks de dados de diferentes comprimentos

Eu tenho dois frameworks de dados.
O primeiro é de apenas uma coluna e 10 linhas.
O segundo é de 3 colunas e 50 linhas.

Quando tento combinar isso usando o cbind , ele apresenta este erro:

Erro no data.frame (…, check.names = FALSE):

Alguém pode sugerir outra function para fazer isso?
PS Eu tentei isso usando listas também, mas dá o mesmo erro.

O quadro de dados que consiste em 3 colunas deve ser as 3 primeiras colunas em um arquivo CSV, enquanto o quadro de dados com uma coluna deve ser a quarta coluna nesse arquivo, quando escrevo com a function write.table . As 3 primeiras colunas têm 50 linhas e a quarta coluna deve ocupar as 10 primeiras linhas.

No pacote plyr , há uma function rbind.fill que mesclará data.frames e apresentará NA para células vazias:

 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 

Não está claro para mim o que o OP está realmente fazendo, dados os comentários subsequentes. É possível que eles estejam realmente procurando uma maneira de gravar os dados no arquivo.

Mas vamos supor que estamos realmente atrás de uma maneira de cbind vários frameworks de dados de diferentes comprimentos.

cbind irá eventualmente chamar o data.frame , cujos arquivos de ajuda dizem:

Objetos passados ​​para data.frame devem ter o mesmo número de linhas, mas vetores atômicos, fatores e vetores de caracteres protegidos por I serão reciclados um número inteiro de vezes se necessário (incluindo a partir de R 2.9.0, elementos de argumentos de lista).

Assim, no exemplo real do OP, não deve haver um erro, pois R deve reciclar os vetores mais curtos como sendo de comprimento 50. De fato, quando executo o seguinte:

 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) 

Não recebo erros e o quadro de dados mais curto é reciclado conforme o esperado. No entanto, quando eu corro isso:

 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) 

Estou tendo o erro a seguir:

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

Mas a coisa maravilhosa sobre R é que você pode fazer quase tudo o que quiser, mesmo que não deva. Por exemplo, aqui está uma function simples que irá cbind frameworks de dados de comprimento irregular e preencher automaticamente os mais curtos com 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)) } 

que pode ser usado assim:

 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) 

Não garanto que essa function funcione em todos os casos; é apenas um exemplo.

EDITAR

Se o objective principal for criar um csv ou arquivo de texto, tudo o que você precisa fazer é alterar a function para "pad "" usando "" ao invés de NA e então fazer algo assim:

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

e então use write.table em rs .

Referindo-se a resposta de Andrie, sugerindo usar plyr::rbind.fill() : Combinado com t() você tem algo como cbind.fill() (que não faz parte do plyr ) que irá construir o seu quadro de dados com a consideração de caso idêntico números.

Minha idéia é obter o máximo de linhas de contagem de todos os frames de dados e, em seguida, append a matriz vazia a cada data.frame, se necessário. Este método não requer pacotes adicionais, somente a base é usada. Código parece seguinte:

 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 

Espero que isto funcione para voce!

Você pode usar a library(qpcR) para combinar duas matrizes com tamanhos diferentes.

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

NOTA: - A matriz resultante será do tamanho da matriz2.

Na verdade, não recebo um erro com isso.

 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) 

Eu usei cartas caso juntar todos os valores numéricos tinha uma funcionalidade diferente (o que não aconteceu). Seu 'primeiro quadro de dados', que na verdade é apenas um vetor ', é repetido apenas 5 vezes na quarta coluna ...

Mas todos os comentários dos gurus para a questão ainda são relevantes 🙂

Acho que descobri uma solução bem mais curta. Espero que ajude alguém.

 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) } 

Apenas meus 2 centavos. Esse código combina duas matrizes ou data.frames em uma. Se uma estrutura de dados tiver um número menor de linhas, linhas ausentes serão adicionadas com valores de 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) 

Eu tive problema semelhante, eu combinei as inputs em uma coluna particular de dois conjuntos de dados e cbind apenas se corresponder. Para dois conjuntos de dados, dados1 e dados2, estou adicionando uma coluna em data1 de data2 depois de comparar a primeira coluna de ambos.

 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] } }