I would like to find a way to create a data.frame by using cbind()
to join together many separate objects. For example, if A, B, C & D are all vectors of eq
You should bare in mind, though, that cbind
will return an atomic vector (matrix) when applied solely on atomic vectors (double
in this case). As you can see in @prasad's and @Aaron's answers, resulting object is a matrix. If you specify other atomic vectors (integer, double, logical, complex) along with character vector, they will get coerced to character. And then you have a problem - you have to convert them to desired classes. So,
if A, B, C & D are all vectors of equal length, one can create data.frame ABCD with
ABCD <- data.frame(A, B, C, D)
Perhaps you should ask "how can I easily gather various vectors of equal length and put them in a data.frame
"? cbind
is great, but sometimes it's not what you're looking for...
You can put all vectors in environment into list using eapply.
obj.list <- eapply(.GlobalEnv,function(x) if(is.vector(x)) x)
obj.list <- obj.list[names(obj.list) %in% LETTERS]
The do.call
function is very useful here:
A <- 1:10
B <- 11:20
C <- 20:11
> do.call(cbind, list(A,B,C))
[,1] [,2] [,3]
[1,] 1 11 20
[2,] 2 12 19
[3,] 3 13 18
[4,] 4 14 17
[5,] 5 15 16
[6,] 6 16 15
[7,] 7 17 14
[8,] 8 18 13
[9,] 9 19 12
[10,] 10 20 11
First you need to get
the objects you want and store them together as a list; if you can construct their names as strings, you use the get
function. Here I create two variables, A
and B
:
> A <- 1:4
> B <- rep(LETTERS[1:2],2)
I then construct a character vector containing their names (stored as ns
) and get
these variables using lapply
. I then set the names of the list to be the same as their original names.
> (ns <- LETTERS[1:2])
[1] "A" "B"
> obj.list <- lapply(ns, get)
> names(obj.list) <- ns
> obj.list
$A
[1] 1 2 3 4
$B
[1] "A" "B" "A" "B"
Then you can use do.call
; the first argument is the function you want and the second is a list with the arguments you want to pass to it.
> do.call(cbind, obj.list)
A B
[1,] "1" "A"
[2,] "2" "B"
[3,] "3" "A"
[4,] "4" "B"
However, as aL3xa correctly notes, this makes a matrix, not a data frame, which may not be what you want if the variables are different classes; here my A
has been coerced to a character vector instead of a numeric vector. To make a data frame from a list, you just call data.frame
on it; then the classes of the variables are retained.
> (AB <- data.frame(obj.list))
A B
1 1 A
2 2 B
3 3 A
4 4 B
> sapply(AB, class)
A B
"integer" "factor"
> str(AB)
'data.frame': 4 obs. of 2 variables:
$ A: int 1 2 3 4
$ B: Factor w/ 2 levels "A","B": 1 2 1 2