Enoana
Enoana

Reputation: 55

Could I subset a data.table by row using logical subsetting and keying?

I would be interested if it is possible to combine logical rowsettings and keying. I show through my code what I mean by that:

dt <-  data.table(var1 = rep(LETTERS[1:5], 2), 
                  var2 = seq(1, 20, 2), 
                  var3 = ceiling(rnorm(10, 3, 2)))

#subsetting by logical expression
dt[var1 == "A" & var2 == 1] # ok
dt[var1 == "A" & var2 == c(1, 3)] # not working due to multiple criteria in var2, keying is necessary

#subsetting by using keys
setkey(dt, var2)
dt[.(c(1, 3))] # ok
dt[.(c(1, 3) & var1 == "A")] # not working, could I make it work?

setkey(dt, var1, var2)
dt[.("A", c(1, 3))] #ok

So clearly I could not manage to combine logical rowsetting and keys but I do not know if my syntax is incorrect or really you cannot combine these two ways to subset? I understand that if I turn all interested columns to keys I can solve the problem.

Upvotes: 0

Views: 55

Answers (2)

deepseefan
deepseefan

Reputation: 3791

The data.table table way is dt[i,j,by], so a column subset is done using j.

# To get a logical use 
dt[,var1 == "A" & (var2 ==c(1,11))]
#TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE

# to return the actual values 
dt[dt[,var1 == "A" & (var2 ==c(1,11))]]

#   var1 var2 var3
# 1:    A    1    4
# 2:    A   11    1

Upvotes: 0

s_baldur
s_baldur

Reputation: 33488

You could do it by specifying the on argument:

dt[.(var1 = "A", var2 = c(1,3)), on = .(var1, var2), nomatch = 0]

Or with chaining as chinsoon12 suggests:

dt[.(c(1, 3))][var1 == "A"]

Upvotes: 1

Related Questions