Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a new method to data.table

I work a lot with time series. Most of my manipulations are done via data.table, but often I have to check data called by specific time, and for that I use xts method:

> timedata['2014-01-02/2014-01-03']

My data.table data is basically the exact copy of xts, with first colums index, containing time:

> dt_timedata <- data.table(index=index(timedata), coredata(timedata))

At some point data became way too large, so keeping both or converting them all the time is not really a good option (which it never was really), so I am thinking about making the same method for data.table. However, I only couldn't find any reasonably easy examples of modifying a generic method.

Is what I want even possible, and if so, where could I read about it?

PS Even though I can abviosly use something like

> from <- '2014-01-02'
> to <- '2014-01-03'
> period <- as.POSIXct(c(from, to))
> dt_timedata[index %between% period]

it is far less intuitive and beautiful, so I would rather write a new method.

Edit1 (example by request)

require(xts)
require(data.table)
days <- as.POSIXct(c('2014-01-01', '2014-01-02', '2014-01-03', '2014-01-04'), origin='1970-01-01')
timedata <- xts(1:4, days)
dt_timedata <- data.table(index=index(timedata), coredata(timedata))

What I can do in xts:

> timedata['2014-01-01/2014-01-02']
       [,1]
2014-01-01    1
2014-01-02    2

I want the exact same for [.data.table.

Edit2 (to illustrate what I do)

'[.data.table' = function(x, i, ...) {
    if (!missing('i')) {  
        if (all(class(i) == "character")) {
            # do some weird stuff
            return(x[ *some indices subset I just created* ])
        }
    }
    data.table:::'[.data.table'(x, i, ...)
}

So basically if i is character and suits my format (checks happen in weird stuff section) I return something and function never goes to the last command. Otherwise nothing happens and I just call

data.table:::'[.data.table'(x, i, ...)

And the thing is, this breaks expressions like

ind <- as.POSIXct('2014-01-01', origin='1970-01-01')
dt_timedata[index==ind]

Here's a trivial example for you to try:

require(data.table)
days <- as.POSIXct(c('2014-01-01', '2014-01-02', '2014-01-03', '2014-01-04'), origin='1970-01-01')
dt_timedata <- data.table(index=days, value=1:4)
ind <- as.POSIXct('2014-01-01', origin='1970-01-01')
# now it works
dt_timedata[index==ind]
# new trivial [.data.table
'[.data.table' = function(x, I, ...) {
    data.table:::`[.data.table`(x, I, ...)
}
# and now it doesn't work
dt_timedata[index==ind]
like image 225
user2794728 Avatar asked Sep 19 '26 15:09

user2794728


1 Answers

Modifying the method to add your own smth smth is very simple:

`[.data.table` = function(...) {
  print("I'm doing smth custom")
  data.table:::`[.data.table`(...)
}

dt = data.table(a = 1:5)
dt[, sum(a)]
#[1] "I'm doing smth custom"
#[1] 15

So just process the first argument however you like and feed it to the standard function.

Here's an example to handle your edit:

`[.data.table` = function(...) {
  if (try(class(..2), silent = TRUE) == 'character')
    print("boo")
  else
    data.table:::`[.data.table`(...)
}

dt = data.table(a = 1:10)
dt[a == 4]
#   a
#1: 4

dt['sdf']
#[1] "boo"
#[1] "boo"
like image 56
eddi Avatar answered Sep 22 '26 07:09

eddi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!