Reputation: 3495
I'd like a function I wrote that expects a data frame to work with data tables just as if they were data frames; e.g., I want d[, j]
to do the same thing whether the argument d
is a data frame or data table.
I know that data.table:::cedta
is used in [.data.table
to detect whether data frame compatibility mode should be on. How do I force it on for a particular function?
Upvotes: 3
Views: 74
Reputation: 66819
If the only problem is what happens inside [.data.table
, you can call [.data.frame
instead:
library(data.table)
DT = data.table(a = 1:2, key="a")
# data.table behavior
`[`(DT, , 1)
# a
# 1: 1
# 2: 2
# data.frame behavior
(function(d) base::`[.data.frame`(d, , 1))(DT)
# [1] 1 2
I guess the base::
prefix probably is not needed. You could also write your function into a non-CEDTA package and load it from there.
Upvotes: 2
Reputation: 5958
Most straightforward way is to differentiate explicitly..
You can detect the class of the argument passed to your function using something like this in your clauses..
a <- c(1,2,3) %>% data.table()
"data.table" %in% class(a)
#[1] TRUE
b <- c(1,2,3) %>% data.frame()
"data.table" %in% class(b)
#[1] FALSE
# Do stuff
To avoid writing the logic twice you could apply as.data.table
to the argument and then you are able to use only one type of syntax.
Upvotes: 1
Reputation: 132706
Use setDF
(and setDT
):
library(data.table)
DT <- data.table(x = 1:2, y = 3:4)
foo <- function(d, j) {
test <- is.data.table(d)
if (test) setDF(d)
res <- d[,j]
if (test) setDT(d) #necessary to avoid changing DT
res
}
foo(DT, 1)
#[1] 1 2
as.data.frame(DT)[, 1]
#[1] 1 2
DT[, 1]
# x
#1: 1
#2: 2
Upvotes: 3