Using Cbind on an Arbitrarily Long List of Objects

cbind dataframes in loop

I don't think that a for-loop would be any faster than do.call(cbind, dfs), but it wasn't clear to me that you actually had such a list yet. I thought you might need to build such list from a character object. This answer assumes you don't have a list yet but that you do have all your dataframes numbered in an ascending sequence that ends in n where the decimal representation might have multiple digits.

 t <- do.call( cbind, mget( paste0("s.dfs", 1:n) ) )

Pasqui uses ls inside mget and a pattern to capture all the numbered dataframes. I would have used a slightly different one, since you suggested that the number was higher than 9 which is all that his pattern would capture:

  ls(pattern = "^s\\.df[0-9]+")  # any number of digits
# ^ need double escapes to make '.' a literal period or fixed=TRUE

Bind vector with list of vectors using cbind

The difference is subtle but important: for your code to work the way you want it you need

b <- do.call(cbind, list(df[1], a))
# ^^^^^

Result

b
# id colB colC
#1 1 110 210
#2 2 120 220
#3 3 130 230
#4 4 140 240
#5 5 150 250
#6 6 160 260
#7 7 170 270
#8 8 180 280
#9 9 190 290
#10 10 200 300

The difference is that df[1] returns a data.frame while df[,1] returns a vector. cbind has a method for data.frames which is what get's called in above case, but not in your case.

cbind arbitrary length vectors with no warning

Here is one option, wrapping the key concept into a function that arranges for things to just work. The simplest way is just to use rep() on each element of ... to repeat each input vecotr in ... to a common length (i.e. the length of the longest input vector).

This is what I do below using the length.out argument of rep().

CBIND <- function(..., deparse.level = 1) {
dots <- list(...) ## grab the objects passed in via ... this is a list
len <- sapply(dots, length) ## find lengths of individual vectors
## this applies rep() over dots extending each component vector to length
## of longest vector in ...
dots <- lapply(seq_along(dots),
function(i, x, len) rep(x[[i]], length.out = len),
x = dots, len = max(len))
## need to put everything together so arrange for a call to cbind
## passing the extended list of vectors and passing along
## the deparse.level argument of cbind
do.call(cbind, c(dots, deparse.level = deparse.level))
}

This gives:

R> CBIND(c(1,2,3),c(4,5))
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 4
R> CBIND(c(1,2,3),c(4,5), deparse.level = 2)
c(1, 2, 3) c(4, 5, 4)
[1,] 1 4
[2,] 2 5
[3,] 3 4

I would certainly favour this over simply clobbering warnings with suppressWarnings() wrapped around the call. For production code you want to explicitly handle the cases you want to allow and let warnings propagate in circumstances where the user has done something you didn't account for.

R - cbind lists ( lm summary )

Try this:

 data<- as.data.frame(data)

Using some sort of bind() function to create a data.frame with coefficients from nested models?

Using this answer from another question:

cbind.fill<-function(...){
nm <- list(...)
nm<-lapply(nm, as.matrix)
n <- max(sapply(nm, nrow))
do.call(cbind, lapply(nm, function (x)
rbind(x, matrix(, n-nrow(x), ncol(x)))))
}

You could do this:

do.call(cbind.fill,lapply(list(model1,model2,model3),function(x){coef(x)}))

[,1] [,2] [,3]
(Intercept) 0.59216966 0.25551154 0.27982881
x1 0.05220228 0.04116431 0.03754457
NA 0.12530141 0.15142340
NA NA -0.02993768

And then set the row and column names manually. (Note that this returns a matrix, not a data frame, if that matters to you.)



Related Topics



Leave a reply



Submit