6

I have a question regarding the characteristics of cbind in a data table and a data frame. If I am binding a data frame(df) and a data table(dt), then the class of the resultant object depends on the first parameter.

example:

> dt<-data.table(x=c(1,2,3),y=c(2,3,4),z=c(3,4,5))
> df<-data.frame(x=c(1,2,3),y=c(2,3,4),z=c(3,4,5))
> dt
   x y z
1: 1 2 3
2: 2 3 4
3: 3 4 5

Case 1:(first parameter as data frame)

>test_df<-cbind(df,dt)
>class(test_df)
[1] "data.frame"

Case 2:(first parameter as data table)

>test_dt<-cbind(dt,df)
>class(test_dt)
[1] "data.table" "data.frame"

So, my question is how is it possible to get the output object as a data table and data frame in two different scenarios, where cbind doesn't have a data.table method.

It is clear in the merge function where R calls different merge functions depending up on the first parameter (if first parameter is a data frame it calls, data frame and if it is a data table, it calls the data table method of merge).

Nakx
  • 1,460
  • 1
  • 23
  • 32
Anuj
  • 303
  • 1
  • 3
  • 13

1 Answers1

5

If you look at the code of cbind.data.frame you see that there's a check for the data.table case:

cbind.data.frame
# function (..., deparse.level = 1) 
# {
#     if (!identical(class(..1), "data.frame")) 
#         for (x in list(...)) {
#             if (inherits(x, "data.table")) 
#                 return(data.table::data.table(...))
#         }
#     data.frame(..., check.names = FALSE)
# }
# <environment: namespace:base>

Rather odd, I'd agree - I would have expected a cbind.data.table method, but I guess there were some good reasons for not doing it.

thothal
  • 16,690
  • 3
  • 36
  • 71
  • 3
    explanation is here: https://cran.r-project.org/web/packages/data.table/vignettes/datatable-faq.html#ive-noticed-that-basecbind.data.frame-and-baserbind.data.frame-appear-to-be-changed-by-data.table.-how-is-this-possible-why – topchef Nov 04 '18 at 06:11