You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Right now when adding multiple columns to a data.table one of the options is to do:
dt[, `:=`(col1=stuff, col2=moar_stuff)]
I think that this syntax can be a bit confusing (too many equals) but mainly is hard to write. To get the grave accent, on my keyboard I have to press AltGr + } and then space. It's kind of annoying.
So my modest proposal is to just have an alias for :=() that is just a run-off-the-mill common name with no special characters. Maybe (ab)using the set() function? It would end up something like this:
dt[, set(col1=stuff, col2=moar_stuff)]
I think it not only reads better, but it's also 87% easier to type.
(I suggested the name list_set there but the idea is the same)
I think the issue is there's a reason why := is not defined as a proper function (limiting the API so prevent its being used outside [)... not sure how challenging it is to build out the NSE hacks to work for a new function in addition to :=.
on my keyboard I have to press AltGr + } and then space. It's kind of annoying.
Sounds very much so! Are you working in RStudio? There must be a way to define some add-in keyboard shortcuts...
I've just realised that this would also make it possible to add columns by reference without explicitly adding names. That is, if list_fun() is a function that returns a named list then you could do something like
dt[, set(list_fun(columns))]
I think it would be cool to stick to the naming convention of starting with set to indicate that is changing something by reference. set_columns()? (too long).
As for the named list in :=, isn't it better to just handle ":="(list(col1=col1, col2=col2))?
Yes, I guess ultimately it's the same change.
setj() could work, but the "j" there is kind of esoteric and I don't know how many users (specially beginners) appreciate that they are using an argument named "j".
setj() could work, but the "j" there is kind of esoteric and I don't know how many users (specially beginners) appreciate that they are using an argument named "j".
Once they will figure that out, looking at ?"[" for example, they will appreciate. These really basics things that anyone who wants to "know R" should learn at some point.
My suggestion to address this issue is an alias setj which will be substituted for := in [.data.table.
I don't know if many users will ever look at ?"[" (I now I never have 😜️). Still, I generally like more descriptive arguments. "j" is basically meaningless --merely a convention from algebra notation-- whereas "column" actually describes what's going on.
How abut setcol()?
I think most (if not all) set* functions take a data.table as input (e.g., setkey, setorder, setcolorder). The most natural syntax to me would be:
DT[, .(col1:=new_value, col2:=something)]
This way no new symbol is introduced; we simply allow for mixing the already well-known .() (~the result consists of multiple columns) and := (~do the assignment in place) symbols.
In my opinion, that would be more confusing because then the behaviour of .() would not be consistent. Sometimes it would create a new data.table and others it would modify by reference. It could further come into problems if someone where to write DT[, .(col1 := new_value, col2 = something)] and the functional version would still be needed for the ":="(list(col1=col1, col2=col2)) case.
I do think its a good point that set* functions take a data.table as argument, though. 🤔
Yeah, but I think the point is that set functions modify (by reference) the object in the x argument. In this case set would be modifying the data.table in which it is called. It's a small departure from the other functions' behaviour, maybe.
To get the grave accent, on my keyboard I have to press AltGr + } and then space. It's kind of annoying.
Btw, just for completeness, both single quote and double quote also work; i.e. DT[, ':='(...)] and DT[, ":="(...)]. It doesn't have to be backtick; i.e. grave. Not saying an alias isn't still better. Will merge PR. Just saying for completeness it doesn't have to be backtick.
Activity
MichaelChirico commentedon Aug 28, 2019
Relatedly it would also help solve this issue:
#1543 (comment)
(I suggested the name
list_setthere but the idea is the same)I think the issue is there's a reason why
:=is not defined as a proper function (limiting the API so prevent its being used outside[)... not sure how challenging it is to build out the NSE hacks to work for a new function in addition to:=.Sounds very much so! Are you working in RStudio? There must be a way to define some add-in keyboard shortcuts...
eliocamp commentedon Aug 28, 2019
That was going to be my second proposal. I've just made one and was thinking if it would make sense to add it to data.table proper.
eliocamp commentedon Aug 28, 2019
I've just realised that this would also make it possible to add columns by reference without explicitly adding names. That is, if
list_fun()is a function that returns a named list then you could do something likeI think it would be cool to stick to the naming convention of starting with
setto indicate that is changing something by reference.set_columns()? (too long).As far as implementation, I have no idea xD
jangorecki commentedon Aug 29, 2019
Note that there is alternative API for
":="(c("col1","col2"), list(col1, col2)).I would prefer to avoid name collision, even if not evaluated. Maybe
setj?As for the named list in
:=, isn't it better to just handle":="(list(col1=col1, col2=col2))?eliocamp commentedon Aug 29, 2019
Yes, I guess ultimately it's the same change.
setj()could work, but the "j" there is kind of esoteric and I don't know how many users (specially beginners) appreciate that they are using an argument named "j".jangorecki commentedon Sep 21, 2019
Once they will figure that out, looking at
?"["for example, they will appreciate. These really basics things that anyone who wants to "know R" should learn at some point.My suggestion to address this issue is an alias
setjwhich will be substituted for:=in[.data.table.eliocamp commentedon Sep 21, 2019
I don't know if many users will ever look at
?"["(I now I never have 😜️). Still, I generally like more descriptive arguments. "j" is basically meaningless --merely a convention from algebra notation-- whereas "column" actually describes what's going on.How abut
setcol()?tdeenes commentedon Sep 23, 2019
I think most (if not all) set* functions take a data.table as input (e.g., setkey, setorder, setcolorder). The most natural syntax to me would be:
This way no new symbol is introduced; we simply allow for mixing the already well-known
.()(~the result consists of multiple columns) and:=(~do the assignment in place) symbols.eliocamp commentedon Sep 23, 2019
In my opinion, that would be more confusing because then the behaviour of
.()would not be consistent. Sometimes it would create a new data.table and others it would modify by reference. It could further come into problems if someone where to writeDT[, .(col1 := new_value, col2 = something)]and the functional version would still be needed for the":="(list(col1=col1, col2=col2))case.I do think its a good point that
set*functions take a data.table as argument, though. 🤔jangorecki commentedon Sep 23, 2019
setattrworks for other typeseliocamp commentedon Sep 23, 2019
Yeah, but I think the point is that
setfunctions modify (by reference) the object in thexargument. In this casesetwould be modifying the data.table in which it is called. It's a small departure from the other functions' behaviour, maybe.dracodoc commentedon Oct 26, 2019
Maybe simply use a different word other than
set? How aboutlet?eliocamp commentedon Oct 27, 2019
That's fine by me. Is not bad.
moodymudskipper commentedon Nov 5, 2019
As far as I can tell it's only about changing
== ":="to%in% c(":=", "let")in the code.I wrote this evil hack for a reddit user that wanted this feature :
s-fleck commentedon Dec 17, 2019
Might I suggest
"mut()"? Seems appropriate for mutating a mutable object :)mattdowle commentedon Nov 30, 2021
Btw, just for completeness, both single quote and double quote also work; i.e.
DT[, ':='(...)]andDT[, ":="(...)]. It doesn't have to be backtick; i.e. grave. Not saying an alias isn't still better. Will merge PR. Just saying for completeness it doesn't have to be backtick.