views:

1089

answers:

3

I've been digging through the documentation for the data.table package (a replacement for data.frame that's much more efficient for certain operations), including Josh Reich's presentation on SQL and data.table at the NYC R Meetup (pdf), but can't figure this totally trivial operation out.

> x <- DT(a=1:3, b=2:4, key='a')
> x
     a b
[1,] 1 2
[2,] 2 3
[3,] 3 4
> y <- DT(a=1:3, c=c('a','b','c'), key='a')
> y
     a c
[1,] 1 a
[2,] 2 b
[3,] 3 c
> x[y]
     a b
[1,] 1 2
[2,] 2 3
[3,] 3 4
> merge(x,y)
  a b c
1 1 2 a
2 2 3 b
3 3 4 c

The docs say "When [the first argument] is itself a data.table, a join is invoked similar to base::merge but uses binary search on the sorted key." Clearly this is not the case. Can I get the other columns from y into the result of x[y] with data.tables? It seems like it's just taking the rows of x where the key matches the key of y, but ignoring the rest of y entirely...

+5  A: 

You are quoting the wrong part of documentation. If you have a look at the doc of [.data.table you will read:

When i is a data.table, x must have a key, meaning join i to x and return the rows in x that match. An equi-join is performed between each column in i to each column in x’s key in order. This is similar to base R functionality of sub- setting a matrix by a 2-column matrix, and in higher dimensions subsetting an n-dimensional array by an n-column matrix

I admit the description of the package (the part you quoted) is somewhat confusing, because it seems to say that the "["-operation can be used instead of merge. But I think what it says is: if x and y are both data.tables we use a join on an index (which is invoked like merge) instead of binary search.


One more thing:

The data.table library I installed via install.packages was missing the merge.data.table method, so using merge would call merge.data.frame. After installing the package from R-Forge R used the faster merge.data.table method.

You can check if you have the merge.data.table method by checking the output of:

methods(generic.function="merge")
f3lix
Ah. It appears as if the version on CRAN is version 1.2, while the version on R-Forge is version 1.3. The `merge` method was apparently added in 1.3. From what I can tell looking around R-Forge, the method was added something like 8 months ago, so I don't know why it's not on CRAN yet!
Harlan
+1  A: 

I think that f3lix is correct and that the documentation is a little misleading. The benefit is in doing a fast join to subset the data. You still ultimately need to use the merge function afterwards as in your above example.

You will see in Josh's presentation on using data.table that this is how his example runs. He first subsets one of the data.tables, then does a merge:

library(data.table)
sdt <- DT(series, key='series_id')
ddt <- DT(data, key='series_id')
u <- sdt[ grepl('^[A-Z]{2}URN', fred_id) & !grepl('DSURN', fred_id) ]
d <- ddt[ u, DT(min=min(value)), by='series_id', mult='all']
data <- merge(d,series)[,c('title','min','mean','max')]
Shane
Thanks, Shane. I was very confused by this, as I knew (or thought I knew) that `merge` would not take advantage of the `data.table` advantages.
Harlan
+2  A: 

Thanks for the answers. I missed this thread when it was originally posted. data.table has moved on since February. 1.4.1 was released to CRAN a while ago and 1.5 is out soon. For example the DT() alias has been replaced with list(); as a primitive its much faster, and data.table now inherits from data.frame so it works with packages that only accept data.frame such as ggplot and lattice, without any conversion required (faster and more convenient).

Is it possible to subscribe to the data.table tag so I get an email when someone posts a question with that tag? The datatable-help list has grown to about 30-40 messages a month, but I'm happy to answer here too if I can get some kind of notification.

Matthew

Hi, thanks for the note! Yes, it's definitely possible. Click on the `data.table` tag box in the upper-right corner of the screen, then scroll to the bottom until you see the RSS icon, and use that to subscribe to questions with this tag.
Harlan
Thanks Harlan. I have subscribed now.