合并两个不同长度的数据帧

我有两个数据框。
第一个只有一列十行。
第二个是3列50行。

当我尝试通过使用进行组合时cbind,出现以下错误:

data.frame(...,check.names = FALSE)错误:

谁能建议另一个功能来做到这一点?
PS我也尝试过使用列表,但这给出了同样的错误。

当我使用该write.table函数编写代码时,由3列组成的数据框应为CSV文件中的前3列,而具有一列的数据框应为该文件中的第四列。前三列有50行,第四列应占前10行。


千巷猫影
浏览 756回答 3
3回答

MM们

在plyr包中,有一个函数rbind.fill将合并data.frames并NA为空单元格引入:library(plyr)combined <- rbind.fill(mtcars[c("mpg", "wt")], mtcars[c("wt", "cyl")])combined[25:40, ]&nbsp; &nbsp; mpg&nbsp; &nbsp; wt cyl25 19.2 3.845&nbsp; NA26 27.3 1.935&nbsp; NA27 26.0 2.140&nbsp; NA28 30.4 1.513&nbsp; NA29 15.8 3.170&nbsp; NA30 19.7 2.770&nbsp; NA31 15.0 3.570&nbsp; NA32 21.4 2.780&nbsp; NA33&nbsp; &nbsp;NA 2.620&nbsp; &nbsp;634&nbsp; &nbsp;NA 2.875&nbsp; &nbsp;635&nbsp; &nbsp;NA 2.320&nbsp; &nbsp;4

莫回无

鉴于后续评论,我尚不清楚OP实际执行的操作。他们实际上可能正在寻找一种将数据写入文件的方法。但是,让我们假设我们确实是在寻找cbind一种不同长度的多个数据帧的方法。cbind最终会致电data.frame,其帮助文件中显示:传递给data.frame的对象应该具有相同的行数,但是,如果有必要,我保护的原子向量,因子和字符向量将被回收多次(包括从R 2.9.0版开始,包括列表参数的元素)。因此在OP的实际示例中,应该不会有错误,因为R应该将较短的向量回收为长度为50的。确实,当我运行以下命令时:set.seed(1)a <- runif(50)b <- 1:50c <- 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)我没有任何错误,较短的数据帧也按预期回收。但是,当我运行此命令时:set.seed(1)a <- runif(50)b <- 1:50c <- 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)我收到以下错误:Error in data.frame(..., check.names = FALSE) :&nbsp;&nbsp; arguments imply differing number of rows: 50, 9但是R的奇妙之处在于,即使您不希望这样做,也可以使它几乎可以做任何您想做的事情。例如,这是一个简单的函数,它将cbind对长度不均匀的数据帧进行数据处理,并使用NAs 自动填充较短的帧:cbindPad <- function(...){args <- list(...)n <- sapply(args,nrow)mx <- max(n)pad <- function(x, mx){&nbsp; &nbsp; if (nrow(x) < mx){&nbsp; &nbsp; &nbsp; &nbsp; nms <- colnames(x)&nbsp; &nbsp; &nbsp; &nbsp; padTemp <- matrix(NA, mx - nrow(x), ncol(x))&nbsp; &nbsp; &nbsp; &nbsp; colnames(padTemp) <- nms&nbsp; &nbsp; &nbsp; &nbsp; if (ncol(x)==0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return(padTemp)&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; return(rbind(x,padTemp))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; else{&nbsp; &nbsp; &nbsp; &nbsp; return(x)&nbsp; &nbsp; }}rs <- lapply(args,pad,mx)return(do.call(cbind,rs))}可以这样使用:set.seed(1)a <- runif(50)b <- 1:50c <- 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)我不能保证此功能在所有情况下都有效。它仅作为示例。编辑如果主要目标是创建一个csv或文本文件,那么您要做的所有事情都会将功能更改为pad ""而不是NA,然后执行以下操作:dat <- cbindPad(dat1,dat2,dat3)rs <- as.data.frame(apply(dat,1,function(x){paste(as.character(x),collapse=",")}))然后write.table在上使用rs。

慕码人2483693

我的想法是获取所有data.frames的最大行数,然后根据需要将空矩阵追加到每个data.frame。此方法不需要其他程序包,仅使用base。代码如下: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) {&nbsp; &nbsp; na.count <- max.rows - nrow(x)&nbsp; &nbsp; if (na.count > 0L) {&nbsp; &nbsp; &nbsp; &nbsp; na.dm <- matrix(NA, na.count, ncol(x))&nbsp; &nbsp; &nbsp; &nbsp; colnames(na.dm) <- colnames(x)&nbsp; &nbsp; &nbsp; &nbsp; rbind(x, na.dm)&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; x&nbsp; &nbsp; }})do.call(cbind, list.df)#&nbsp; &nbsp; &nbsp;a&nbsp; a&nbsp; a# 1&nbsp; &nbsp;1&nbsp; 1&nbsp; 1# 2&nbsp; &nbsp;2&nbsp; 2&nbsp; 2# 3&nbsp; &nbsp;3&nbsp; 3&nbsp; 3# 4&nbsp; &nbsp;4&nbsp; 4 NA# 5&nbsp; &nbsp;5&nbsp; 5 NA# 6&nbsp; &nbsp;6 NA NA# 7&nbsp; &nbsp;7 NA NA# 8&nbsp; &nbsp;8 NA NA# 9&nbsp; &nbsp;9 NA NA# 10 10 NA NA
打开App,查看更多内容
随时随地看视频慕课网APP