6

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
NelsonGon
  • 13,015
  • 7
  • 27
  • 57
eclo.qh
  • 155
  • 1
  • 2
  • 8
  • 2
    `do.call("rbind", ls)` returns a matrix, not a data frame. Same with `rbind(ls)`. – Rich Scriven Jan 28 '16 at 23:41
  • 3
    Because `do.call` extracts the elements out of the list- that's the difference. As if you would do `rbind(ls[[1]], ls[[2]])` – David Arenburg Jan 28 '16 at 23:43
  • Thank you @RichardScriven, but the output of `rbind(ls)` is still a list. Actually what I want is to convert a list to a matrix – eclo.qh Jan 28 '16 at 23:43
  • 3
    No, the output of `rbind(ls)` is a matrix. It contains list elements. See `class(rbind(ls))` – Rich Scriven Jan 28 '16 at 23:44
  • If I use `> str(ls)`, it says it is a list. Though both do.call("rbind", ls) and rbind(ls) return a matrix, the outcome of them are different – eclo.qh Jan 28 '16 at 23:49
  • Thank you @jenesaisquoi, so the difference lies in combinding two list and combinding two elements. – eclo.qh Jan 28 '16 at 23:51
  • Thank you so much @DavidArenburg. It helps. – eclo.qh Jan 28 '16 at 23:52
  • 1
    Because you should read the help page of the function before asking such a question. `?do.call` – alexwhitworth Jan 29 '16 at 00:12
  • It is common sense to check the help page and search this question in stackoverflow before asking. If I didn't get the solution, I will post it here. @Alex – eclo.qh Jan 29 '16 at 01:08

1 Answers1

9

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.

AdamO
  • 4,283
  • 1
  • 27
  • 39