Repository navigation
Allow ! on LHS of := #4031
Description
Activity
I've already been confused by the use of
!in data.table and this one gave me pause too (it's not obvious that we mean "not this column" and not, "negate the values of this variable".I think this ambiguity can be avoided by having select helpers in the style of https://www.rdocumentation.org/packages/dplyr/versions/0.7.2/topics/select_helpers
We would have :
dt[ , !one_of(keep) := NULL]And then all other useful select helpers would work as well :
dt[ , starts_with("Petal") := NULL]In tidy select those helpers return numeric indices, so to use several helpers we need to use set functions like
intersect(),union()andsetdiff(), I'm not sure why this design choice was made, I think logical output makes more sense and allows more compact syntax using|and&.So for this to work the select helpers should detect the data table context and
[.data.tableshould allow logical indices on the lhs of:=inj.Allowing functions on the rhs would go with this quite well, so we could do things like :
dt[, sapply(.SD, is.factor) := as.character] # or dt[, sapply(.SD, is.factor) := as.character(.)]I am not sure about
!keep. Ifnames(.SD)will work in LHS thenkeep = c('Species', 'Sepal.Width') dt[ , setdiff(names(.SD), keep) := NULL] setcolorder(dt, keep)
Reacted by chinsoon12Upvoting this feature. Column selection and deletion are bread and butter of data manipulation. It is not intuitive to
setdiffnames of columns and then delete them. It involves two extra steps for code author and not intuitive to be read by colleagues or collaborators. It is like typing--1(double negative signs) to get1. I am hoping to see a direct way of selecting column using reference semantics.keep = c("Species", "Sepal.Width") dat[ , keep := KEEP]
or a more general but less direct approach, as proposed by @MichaelChirico. This is also similar to typing
--1to get1but the codes are much simpler.dat[ , !keep := NULL] # or dat[ , -keep := NULL]
Another route would be a helper function on
jto combine.SDcolswithj. Use cases:dt[, update.at(is.factor, as.character)] dt[, update.at(!keep, NULL)] dt[, delete.at(!keep)] dt[, select.at(keep)] dt[, select.at(keep, x+ 3)]With
names(.SD)available on LHS of:=, this now works:dt[ , names(.SD) := NULL, .SDcols=!keep]
Closing here, please open other FRs if there's still something missing.
Related to #571, #1710, a few others about allowing NSE on LHS of :=.
Based on the example given here:
#4030 (comment)
Would be quite natural/less clumsy/available for chaining to do: