考虑到后续的 cmets,我根本不清楚 OP 究竟在追求什么。他们可能实际上正在寻找一种将数据写入文件的方法。
但是让我们假设我们真的想要cbind 多个不同长度的数据帧。
cbind 最终会调用data.frame,其帮助文件显示:
传递给 data.frame 的对象应该有相同的行数,但是
受 I 保护的原子向量、因子和字符向量将是
如有必要,可循环多次(包括从 R
2.9.0,列表参数的元素)。
所以在 OP 的实际示例中,不应该出现错误,因为 R 应该将较短的向量回收为长度为 50。确实,当我运行以下命令时:
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)
我没有收到任何错误,并且较短的数据帧按预期回收。但是,当我运行它时:
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)
我收到以下错误:
Error in data.frame(..., check.names = FALSE) :
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){
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))
}
可以这样使用:
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)
我不保证此功能在所有情况下都有效;仅作为示例。
编辑
如果主要目标是创建 csv 或文本文件,您只需将函数更改为使用 "" 而不是 NA 填充,然后执行以下操作:
dat <- cbindPad(dat1,dat2,dat3)
rs <- as.data.frame(apply(dat,1,function(x){paste(as.character(x),collapse=",")}))
然后在rs 上使用write.table。