Reputation: 2368
I have a data.table
library(data.table)
testDT <- data.table(
L = (1:32),
M = rep(letters[23:26], each = 64),
N = rep(LETTERS[1:2], times = 2, each = 512),
O = rnorm(2048, 1))
testDT$L <- factor(testDT$L, levels = seq(from = 1, to = 32, by = 1))
I created a function to subset the data set conditionally. If the subsetting variable G
is NULL
and H
is "w"
, then I want all values within testDT$N
and all values "w"
in testDT$M
to be returned in testDT
. This is what I created, which does not function correctly:
G <- NULL
H <- "w"
testDT1 <- testDT[if(is.null(G)) {eval(call("%in%", as.name("N"), G))} &
if(is.null(H)) {eval(call("%in%", as.name("M"), H))}]
I verified that everything but the if(is.null())
portion works by creating this, which subsets correctly:
G <- "A"
H <- "w"
testDT1 <- testDT[{eval(call("%in%", as.name("N"), G))} &
{eval(call("%in%", as.name("M"), H))}]
How can I use the is.null()
condition correctly?
Upvotes: 3
Views: 686
Reputation: 16697
Using computing on the language you can prepare call
object using dedicated function.
library(data.table)
testDT = data.table(
L = factor(1:32),
M = rep(letters[23:26], each = 64),
N = rep(LETTERS[1:2], times = 2, each = 512),
O = rnorm(2048, 1)
)
i.expr = function(var, x){
if(is.null(x)) TRUE
else call("%in%", as.name(var), x)
}
G = NULL
H = "w"
i.expr("N",G)
#[1] TRUE
i.expr("M",H)
#M %in% "w"
testDT1 = testDT[eval(i.expr("N",G)) & eval(i.expr("M",H))]
G = "A"
H = "w"
i.expr("N",G)
#N %in% "A"
i.expr("M",H)
#M %in% "w"
testDT2 = testDT[eval(i.expr("N",G)) & eval(i.expr("M",H))]
If you always subset by two conditions and &
operator. I would merge it into a single function so you can call it once using testDT[eval(i.expr(...))]
.
Upvotes: 3