I want to convert a list to a data frame, with the following code:
ls<-list(a=c(1:4),b=c(3:6))
do.call("rbind",ls)
The result obtained by adding do.call is as shown below. It returns a data.frame
object as desired.
do.call("rbind",ls)
[,1] [,2] [,3] [,4]
a 1 2 3 4
b 3 4 5 6
However if I directly use rbind
, it returns a list.
Why does rbind
behave differently in these two situations?
my.df<-rbind(ls)
str(ls)
my.df
a b
ls Integer,4 Integer,4
str(ls)
List of 2
$ a: int [1:4] 1 2 3 4
$ b: int [1:4] 3 4 5 6
do.call(rbind, ls)
gives you the same output as Reduce(rbind, ls)
. The later is less efficient, but it serves to show how you are iterating over the objects in ls
rather than manipulating ls
(which is a concatenated list of 2 lists) directly.
They both operate by "unlisting" each element of the list, which has class numeric
. When you rbind
numeric arguments, the resulting class is a matrix with typeof
being integer. If you just rbind
the list, each element of the list is considered a single object. So the returned object is a matrix
object with 1 row and 2 columns and entries of type list
. That it has 1 row should make it apparent it's treating the object ls
as one thing, and not two things. Typing rbind(ls, ls, ls)
will give 3 rows and 2 columns.