require(data.table) # devel compiled on 3rd March 2018
dt <- data.table(x=1:5, y=6:10, z=11:15)
# x y z
# 1: 1 6 11
# 2: 2 7 12
# 3: 3 8 13
# 4: 4 9 14
# 5: 5 10 15
ăăă§ă揥ăŽăăăŤäžżĺŠăŞ..
襨č¨ă使ç¨ăăŚĺăăľăăťăăĺă§ăăžăă
cols <- "z"
dt[, ..cols]
# z
# 1: 11
# 2: 12
# 3: 13
# 4: 14
# 5: 15
..var
ăŻé常ăŤçšĺĽăŞćĺłăćăŁăŚăăăŽă§ăăăă訹ĺŻăăăă¨ăă§ăăžăăďź
dt[, c(..cols, "x")]
çžĺ¨ă揥ăŽăăăŤă¨ăŠăźăçşçăăžăă
# Error in eval(jsub, SDenv, parent.frame()) : object '..cols' not found
ăăžăčăăŚăăžăăă§ăăă迡ĺăŤăŞăăŞăăăăŤăĺşăăăăŚĺéĄă¨ăăŚćĺşăăăăŁăă ăă§ăă
ăăĄăăă dt[ , c(cols, 'x'), with = FALSE]
ăžă ćŠč˝ăăžă... with = FALSE
ăĺŽĺ
¨ăŤćŽľéçăŤĺťć˘ăăăă¨ăăŚăăăăŠăăă¨ăăçĺăĺăłçşçăăžă
ăăăŻăăă§ăăă SynergistăŤăăďź633ăŽĺć§ăŽă˘ă¤ăă˘ăŻćŹĄăŽă¨ăăă§ăă
dt <- data.table(x = 1:10, y = rnorm(10), z = runif(10)) cols <- c('y', 'z') dt[, !..cols] # should return col x
ăăŽă¨ăăă 1.10.2ăŽĺ ăŽăăĽăźăšé çŽďź2017ĺš´1ćďź
jă..ă§ĺ§ăžăăˇăłăăŤăŽĺ ´ĺăĺźăłĺşăăšăłăźăă§ć¤ç´˘ăăăăăŽĺ¤ăŻĺĺăžăăŻçŞĺˇă¨čŚăŞăăăžăă
myCols = cďź "colA"ă "colB"ďź
DT [ămyColsăwith = FALSE]
DT [ă.. myCols]ďźĺă
..ăăŹăăŁăăŻăšă襨示ăăăăă茪ăăŁăŹăŻăăŞăćĺłăăăăšăŚăŽăŞăăŹăźăăŁăłă°ăˇăšăă ă§ăăŁăŹăŻăăŞ..ăŽăăăŤ1ă¤ä¸ăŽăŹăăŤăčăăžăă ĺ°ćĽçăŤăŻă..ăăŹăăŁăăŻăšăŻăDT [...]ĺ ăŽäťťćăŽĺ ´ćăŤčĄ¨ç¤şăăăăăšăŚăŽăˇăłăăŤă§ćŠč˝ăăăăăŤä˝ćăăăĺŻč˝ć§ăăăăžăă ăăăŻă誤ăŁăŚĺĺăĺĺžăăăă¨ăăăłăźăăäżčˇăăăăăŽäžżĺŠăŞćšćłă¨ăŞăăă¨ăçŽçă¨ăăŚăăžăă ăŠăŽăăăŤxăŤäźźăŚăăžăă ăăăŚç§ă ăăŹăăŁăăŻăšďźSQLăăźăăŤă¨ă¤ăŞă˘ăšăŤéĄäźźďźăŻăxă¨iăŽä¸ĄćšăŤĺĺ¨ăăĺăĺĺăć確ăŤăăăăăŤăă§ăŤä˝żç¨ă§ăăžăă ĺźă§ĺŽĺ ¨ăŤä˝żç¨ăăăăšăłăźăăŽĺźăłĺşăăŤĺ¤ăăŽĺ¤ć°ăăăĺ ´ĺă..ďźďźé˘ć°ă§ăŻăŞăăˇăłăăŤăăŹăăŁăăŻăšă使ç¨ăăă¨ăĺ é¨ă§ćéŠĺăăăŽăç°ĄĺăŤăŞăăäžżĺŠăŤăŞăăžăă ăăŽćŠč˝ăŻ2012ĺš´ăŤćĺăŤéçşăăăéˇăéćăžăăŚăăďź633ă§ăă ĺŽé¨çă§ăă
é˘éŁăăćă太ĺăŤăăžăăă ĺ˝ćăŻăăăăăăŞăăŁăăŽă§ăçśčĄăăĺăŤăăŁăźăăăăŻăćĺž
ăăŚăăžăăă ăăăŞăăăăăŻăăžăăăăăă§ăă IIRCăŻăăžă ăłăźăă確čŞăăŚăăžăăăăĺźăłĺşăăšăłăźăă§ç˘şčŞăăăăăŤget()
ăăăł/ăžăăŻăăăăeval()
ăŽăăšăŚăŽĺ¤čŚłăŽç˝Žćăăă§ăŤčĄăăăŚăăăăăăăăťăŠéŁăăăăăžăăă ăă¤ăŚç§ăŻeval()
ăăăšăłăźăăŽĺźăłĺşăăŤăăăčŠäžĄăăäźăăăăăŽĺŞăăăŠăăăźă ă¨ćăŁăŚăăžăăăă [...]
ăŻăă§ăŤăăăčĄăŁăŚăăăŽă§ăŻăŞăăă¨ćăăžăă äťăç§ăŻ..
ăăŹăăŁăăŻăšă弽ăżăžăăăăăŻăăăăˇăłăăŤă§ĺ
ç˘ă ăăă§ăă ..
ăŻăˇăłăăŤăŽăăŹăăŁăăŻăšă§ăăăăăăˇăłăăŤă§ăŞăăă°ăŞăăŞăăă¨ăăăăŁăŚăăžăďź paste(...)
ăŞăŠăŤć¸ĄăăăĺŻč˝ć§ăŽăăeval()
é˘ć°ă¨ăŻç°ăŞăăžăďźă
ăăă§ăŽćčżăŽăă¤ăźăăčŻĺŽçăŞĺĺżă示ăăăăă§ăă
https://twitter.com/MattDowle/status/967290562725359617
čŻăďź ç§ă弽ăă§ăă ăžăăĺŽčŁ ăăă¨ă揥ăŽăăăŞĺéĄăŤĺŻžĺŚăăžăă
dt[x > x]
ăăŽĺžă揥ăŽăăăŤĺŽčĄă§ăăžăă
dt[x > ..x]
@MichaelChiricoç§ăŻăŤĺşăĽăăŚăąăźăšă ă¨äťŽĺŽhttps://github.com/Rdatatable/data.table/issues/2620
ăă掾éă§ăĺä¸ăŽ.
ăăŹăăŁăăŻăšă使ç¨ăăŚăăăăŽăšăłăźăă確ĺŽăŤăăćĺłăăĺĺă§ăŞăĺ ´ĺăŻăšăłăźăăĺźăłĺşăăŞăă¨ăăććĄăăăŁăă¨ćăăžăďźăăăăĺä¸ăŽ.
ă¨ĺć§ă§ăďźă ..
使ç¨ăăŚăšăłăźăăĺźăłĺşăĺż
čŚăăăăăăŽăăŹăăŁăăŻăšăăŞăĺ ´ĺăăˇăłăăŤăŻĺĺă§ăăĺż
čŚăăăăžăă ç ´ćăŽĺŻč˝ć§ăăăĺ¤ć´ă§ăăăé常ăŽćšćłă§çŽĄçăăăžăăăă¨ăă°ăoptionsďźdatatable.strict.scopeďźFALSEăăĺ§ăăŚăć°ĺš´ăŤăăăŁăŚéçĽă¨čŚĺă¨ă¨ăăŤĺžă
ăŤTRUEăŤĺ¤ć´ăăăžăă ăăŽĺ ´ĺăĺźăłĺşăăšăłăźăă§ć¤ĺşăăăăˇăłăăŤăĺŽčĄćăŤć¤ĺşăăăăăăŠăŽăˇăłăăŤăŤ..
ăăăŹăăŁăăŻăšă¨ăăŚäťăăăăćŁç˘şăŤç¤şăčŚĺăé常ăŤé˛ăă§ăăĺŻč˝ć§ăăăăžăă ĺ
ç˘ć§ă¨čŞăżăăăă¸ăŽç§ťčĄă§ăăăä˝ĺš´ăŤăăăăŁăŚăŚăźăśăźăčŞĺăŽćéă§ĺ¤ć´ăĺ ăăăă¨ăă§ăăăăăăŚăźăśăźăŻăăăćăă§ăăă¨ćăăžăă
..
ăŻăĺźăłĺşăăšăłăźăăŤĺ°éăăăăăŤä˝żç¨ăăĺż čŚăăăăăăŽăăŹăăŁăăŻăšăăŞăĺ ´ĺăăˇăłăăŤăŻĺĺă§ăăĺż čŚăăăăžăă
https://github.com/Rdatatable/data.table/issues/697#issuecomment -46305236ăčŚăă¨ă i
ĺ
ăŽĺä¸ăŽăˇăłăăŤăŽäžĺ¤ăäżćăăăă¨ćăăžăďźçľĺă¨ăăŚč§Łéăăăăăă ..
ăŞăăŚăăšăłăźăăĺźăłĺşăĺ ´ĺďźďź
ăăźăăăŻăă éăăŻă i
ĺ
ăŽĺä¸ăŽč¨ĺˇăĺĺăćĺłăăĺ ´ĺăćĺłăăŞăăă¨ă§ăă ăă ăăăăŽĺăăżă¤ălogical
ă ĺäşşçăŤDT[someCol==TRUE]
ă¨ăŤăă
ăăă漽ăăżăŤăăŚăăžăďź ăăăŻăăăŁăąăăŤăŞăŁăŚăăć¸ăăăłăźăăŽăťă¨ăăŠăćŁăăăeval
/ parse
/ quote
/ get
ăăźăăăźăă罎ăćăăĺŻč˝ć§ăăăăăă§ădata.table
ă
ç§ăŽ1ă¤ăŽăă¤ăăŽĺ¤˘ăŻă揥ăŽăăăŤăŞăăžăă严ćšăŽĺźă§ĺăĺşĺăĺžăăăžăă ďźç§ăăăăăżă¤ăăĺ§ăăă¨ăăç§ăŻăăăăăăŤçžĺŽçă§ăăăăŠăăçĺăŤćăĺ§ăăžăăďź
set.seed(1234)
DT <- data.table(foo = rep(LETTERS[1:2],8),
bar = rep(letters[17:20],4),
month = rep(month.name[1:4],4),
day = seq_len(16),
yyy = rnorm(16,mean = 0.5,1.5))
## Expression 1: with hard coded columns
DT[yyy > 0,.(NewCol = paste(month, day),
bar,
yyy), by = foo]
## Expression 2: everything passed by reference
A = "yyy"
B = 0
C = "NewCol"
D = "month"
E = "day"
G = "foo"
H = c("bar","yyy")
DT[..A > ..B , .(..C = paste(..D, ..E),
..H), by = ..G]
`` `
foo NewCol bar yyy
1ďźB 2ć2ćĽr0.9161439
2ďźB 2ć6ćĽr1.2590838
3ďźB 2ć14ćĽr0.5966882
4ďźB 4ć16ćĽt0.3345718
5ďź3ć3ćĽ2.1266618
6ďź1ć5ćĽq 1.1436870
7ďź3ć15ćĽ1.9392411
However, even as I write this I'm starting to see some potential hang-ups, in particular with how the `i` part of the expression is evaluated.
In the case below, it does seem like there is potential ambiguity in whether `..B` would be treated as a column name if a column `xyz` existed in DT. Is my interpretation anywhere close to what you're currently planning on implementing, and should I perhaps be using a single `.` notation in some places?
```r
A = "foo" ## intended column name
B = "xyz" ## intended literal character string for comparison
DT[..A == ..B]
ĺŽčŁ ăăăăăŽăä˝ă§ăăăç§ăŻăăă漽ăăżăŤăăŚăăžăďź
ăăă¤ăăŽé˘éŁăăăšăżăăŻăŞăźăăźăăăźăŽčłŞĺďźăăăŤĺŻç¨żč ăăăŽĺ¤ăăŽĺçăăăăžăďźďź
ăăŚăăăšăżăźăŤăŞăăžăăă äťăŽă¨ăăj=
ă§ä˝żç¨ăăăŚăăč¨ĺˇăŤă¤ăăŚăŽăżă
ăăšăŚčŠŚăăŚăżăŚăă ăăă
NEWSă˘ă¤ăă ă¨PRďź2704ăŽć°ăăăăšăăĺç
§ăăŚăă ăăă
@msummersgillăŽăłăĄăłăăäťăă芳ăăčŚăă¨ă2ă¤ăŽç°ăŞăă˘ă¤ăă˘ăăăăăă§ăă
ĺĺă使ç¨ăăj
ĺźă§ä˝żç¨ăăăăăŤăĺźăłĺşăăšăłăźăă§ĺ¤ć°ăŽĺ¤ăăă§ăăăăžăă äžďź beta=10L; DT[, sum(colB)*..beta]
ă beta
ă¨ăăĺăćă¤DT
ĺŻč˝ć§ăăŞăéăăăăăŻăă§ăŤďźăăźăżçăŽ..
ăăŹăăŁăăŻăšăŞăă§ďźćŁĺ¸¸ăŤćŠč˝ăăžăă ..
ăŻăăăăăĺŽĺ
¨ăŤăăžăă
j=
ĺźă§ĺĺă使ç¨ăăžăă使ç¨ăăĺĺăŻăĺźăłĺşăăšăłăźăăŽĺ¤ć°ăŤăăŁăŚĺŽçžŠăăăžăă ..
ăăŹăăŁăăŻăšăĺŽčŁ
ăăăăŽă§ăăăăŻget(..whichCol)
ă§ç˘şĺŽăŤĺŽčĄă§ăăăăăŤăŞăăžăăăăăă§ă whichCol
ăŻĺźăłĺşăăšăłăźăĺ
ăŤăăăăăŽDT
ăăăžă§ăŤçşçăăĺ ´ĺă§ăćŠč˝ăăăăăŤăŞăăžăăă whichCol
ă¨ăăĺăĺŤăžăăŚăăžăă ăă ăă get()
ă使ç¨ăăăŽăŻĺ°ăé˘ĺă§ăĺ
é¨ă§ćéŠĺăăăŽăŻĺ°ăéŁăăă§ăďźçžĺ¨ă get
ăŻăăăšăŚăŽĺăĺźăłĺşăăŚ.SD
ăŤé
罎ăăžăďźă ăăăŤăĺźăłĺşăăšăłăźăăŽwhichCol
ăĺŽéăŤăŻĺĺă§ăŻăŞăĺĺăĺŤăžăăŚăăĺŻč˝ć§ăăăăžăă ăăŽĺ ´ĺă get()
čŞä˝ăĺźăłĺşăăšăłăźăă調ăšăéăćŞăăă°ăĺźăłĺşăăšăłăźăă§ćĺłăăŞăĺ¤ăĺĺžăăĺŻč˝ć§ăăăăžăă get-that-cââolumnă確ĺŽăŤĺĺžăăăăăŽć§ćăăăăłăă䝼ĺ¤ăŽĺ ´ĺăŻă¨ăŠăźăăăă°äžżĺŠă§ăă
ç§ăŻăăăžă§ăąăźăš1ăŤă¤ăăŚăŽăżčăăŚăăžăăăăăăă@arunsrinivasanăăăŽĺéĄăć辡ăăăăŽă§ăăă @ franknarf1ă¨@MichaelChiricoăŻăăăŤé˘ăăăăăŞăäžăŤĺćăăžăăă ăăăăçžĺ¨ăăźă¸ăăăŚăăPRăčĄăăă¨ă§ăă
ăăăă @ msummersgillăŻăăžăŁăăç°ăŞăä˝ăăććĄăăŚăăžăďźăąăźăš2ďźăăăăžă§čăăăă¨ăŻăăăžăăă§ăăă ăăăŻă¨ăŚăç´ ćľăŞă˘ă¤ăă˘ă§ăç§ăŻăăă弽ăă§ăă ăăŽĺ ´ĺăăąăźăš2ăŤĺĽăŽăăŹăăŁăăŻăšăĺż čŚă§ăăăăăăĺż čŚă§ăăďź
ç§ăăăăžă§ćŁăăç解ăăĺ ´ĺătidyevalăŽ!!var
ăŻăŠăŽăăăŞĺ ´ĺăŤăŞăăžăăďź
䝼ćĽDT[, ..cols]
ďźăăă§ăăăŞăăĄj=
ĺŻä¸ăŽăąăźăšă ăŁăăĺä¸ăŽăˇăłăăŤă§ăăăďź ..
ĺăŤĺăăŚăăăç§ăŻçşăăŚăăćšćłăčŚăŚ..
ć掾ăăăžăget
ăçľćăăăžăăă ăăăă ..cols
ăăăžăăžăăă§ä˝żç¨ăăăŚăăă ăă§ă ..cols
ăŻăăăŽăłăłăăăšăă§ăăŽĺăăžăăŻăăĺ¤ăăŽĺ ´ĺăŻĺăŽăťăăăé¸ćăăăă¨ăćĺłăăžăă
ăăăŚäťăç§ăŻă @ msummersgillă彟ăŽăłăĄăłăăŽćĺžăŤăăăăŽ2ă¤ăŽăąăźăšăăă§ăŤčŠłčż°ăăŚăăăŽăčŚăăăç§ăŻăăă䝼ĺăŤćśĺăăŞăăŁăă
解ćăăăŞăăăă _
ăžăăŻ__
ăăŹăăŁăăŻăšăäťăăăă¨ăă§ăăŞăăăă§ăă _
ăžăăŻ__
ćĽĺ°žčžăäťăăăă¨ăă§ăăžăă ăăăăç§ăŻăŠăăăăăăăćĽĺ°žčžăăăćĽé čžăćŹĺ˝ăŤĺĽ˝ăă§ăă
ăăăăç§ăŻăĺ¤ĺ@whichCol
ă ă¨ćăăžăăă ăăăŻget(..whichCol)
ăćĺłăăžăăă whichCol
ăŽĺ¤ăŻĺĺă§ăăĺż
čŚăăăăăăă§ăŞăĺ ´ĺăŻă¨ăŠăźăŤăŞăăžăă ăăăăăăă解ćăăžăăă
ă¤ăžăăĺ¤ăEVAL = parseďźtext = pasteďźďźďźďźăćăăŚăăăŽă§ăç§ăŻăžăŁăăć°ăŤăăžăăăăEVALăŠăăăźă使ç¨ăăŚăăĺ ´ĺă§ăĺ°ăéăăŞăĺŻč˝ć§ăăăăžăă çš°ăčżăăžăăă @ msummersgillăăă§ăŤ
ă ăăăăăăSăŽäžăă¨ăă¨ăăŠăă§ăăďź
DT[ " <strong i="17">@A</strong> > <strong i="18">@B</strong> , .(<strong i="19">@C</strong> = paste(<strong i="20">@D</strong>, @E), @H), by = <strong i="21">@G</strong> " ]
ăŤăźăŤăŻďźfreadăŽćĺăŽĺźć°ăŤĺ°ăäźźăŚăăžăďź i=
ă1ă¤äťĽä¸ăŽ@ăĺŤăćĺĺă§ăăĺ ´ĺăăăźăŻăłç˝Žćă˘ăźăăŤĺăćżăăăžăă ăăŽă˘ăźăă§ăŻăäťăŽăăšăŚăŽĺźć°ďź j=
ă by=
ăŞăŠďźăćŹ č˝ăăŚăăĺż
čŚăăăăžăă ĺ
é¨ăŻăăźăŻăłă罎ăćăăŚăăĺ解ćăăžăă ĺŽčŁ
ăŻăăăťăŠéŁăăăŞăăăăăăžăăă
ăăŽäťăŽäžďź
col = "x"
DT[, ..col] # select column "x" (even if "cols" is a column name too)
DT[, c(..col, "y")] # select columns "x" and "y"
thresh = 6.5
DT[ x > ..thresh ] # select rows where "x" column > 6.5
DT[ "<strong i="29">@col</strong> > y" ] # same as DT [ x > y ] i.e. comparison of two columns
anyString = "..thresh"
DT[ "<strong i="30">@col</strong> > @anyString" ] # same as DT[ x > ..thresh ]
@
ăăŹăăŁăăŻăšă解ćăăăŞăăŽăŻăčŚčŚçăŤăŻäťăŽé常ăŽRăłăźăă¨ĺşĺĽă§ăăăăăĺŽéăŤăŻĺŠçšă§ăă ĺśéăŻăăăźăŻăłç˝Žćă˘ăźăă§ăŻS4ăŽobj @slotăç´ćĽä˝żç¨ă§ăăŞăăă¨ă§ăă ă obj @ slot ăăăăźăŻăłăŽĺ¤ăŤç§ťĺăăĺż
čŚăăăăžăă @
ă§ăăĺż
čŚăŻăăăžăăă ăăăŻä˝ă§ăăăžăăžăăă ăăśă$
ăžăăŻ$$
ăăŹăăŁăăŻăšă§ăćĺĺăŽ$ăäźăăžăă
@
ă罎ăćăă1ă¤ăŽćĺĺăŽă˘ă¤ăă˘ăŻĺĽ˝ăă§ăŻăăăžăăă ăŚăźăśăźăŻbquote
ă使ç¨ăăŚĺźăŽĺ¤ć°ăç°ĄĺăŤç˝Žăćăăăă¨ăă§ăăăăăŻăăĺşćŹçăŞRăŽćšćłăŤă¨ăŠăžăăžăă ć°ăăăŤăšăżă č¨č¨ăăăłäżĺŽăăăAPIăŻăăăžăăă
ăăă°ăŠă ăŽčŚłçšăăăăŚăźăśăźăŻ1ă¤ăŽéˇăćĺĺăä˝ćăăăăăDT[i=
渥ăĺż
čŚăăăăžăă ăăăťăŠĺ
ç˘ă§ăŻăăăžăăă ăŞăšăăĺăĺ
Ľăăă¨ăăăă°ăŠă çăŤăŻăăăŤä˝żăăăăăŞăăćçľçăŤăŻhttps://github.com/Rdatatable/data.table/issues/1579#issuecomment-194323194ăŽăăăŤăŞă
Janăćĺĺăăăĺźă弽ăăă¨ăŤĺćăăžăă ăă1ă¤ăŽă˘ă¤ăă˘ďź get
/ mget
ăăăŞé˘ć°ăčż˝ĺ ăăžăăăăăăŻdata.tableăŽĺăŽéă§ăŽăżčĄ¨ç¤şăăăžă..ďź
DT = data.table(x = 1, y = 2)
cols = c("x", "y")
DT[, ..cols] # as now
DT[, g(..cols)] # same
DT[, g(cols)] # same
DT[, g(..cols), strict=TRUE] # same
DT[, g(cols), strict=TRUE] # error: symbol cols is column name in DT
# nor an external variable highlighted with a .. prefix
# behaving like mget but checking for col names
cols = c("x", "y")
DT[, lapply(g(..cols), max)] # same as current behavior of DT[, lapply(mget(cols), max)]
v = "z"
DT[, {z = 4; lapply(g(..v), max)] # error: selected column "z" not found
# in contrast with DT[, {z = 4; lapply(mget(v), max)}]
# simplifying for a single col by default
vv = "x"
DT[, g(..vv)] # same as DT[, x] with simplification from list to vector
DT[, g(..vv, simplify = FALSE)] # same as DT[, .(x)]
ĺŽçžĺŻč˝ć§ăŤă¤ăăŚăŻä˝ăçĽăăžăăăăăăŽăăăŞăăŽăŻç解ăăăăăćąăăăăă¨ćăăžăă
https://github.com/Rdatatable/data.table/issues/1712#issuecomment-220402452ăăăłhttps://github.com/Rdatatable/data.table/issues/633ăŤé˘éŁ
ć確ăŤăăăăăŤăăăăŤăăăăŽäžăŽçżťč¨łăăăăžăďź
col = "x"
DT[, ..col] # DT[, .(x)]
DT[, c(..col, "y")] # DT[, .(x, y)]
DT[ g(col) > y ] # same as DT [ x > y ]
DT[ g(col) > y, strict=TRUE ] # error: symbol col is not a column name nor highlighted with ..
DT[ g(..col) > y, strict=TRUE ] # same as DT [ x > y ]
thresh = 6.5
DT[ x > ..thresh ] # same as DT[ x > 6.5 ]
DT[ x > thresh, strict=TRUE] # error: symbol thresh is not a column name nor highlighted with ..
DT[ g(col) > ..thresh ] # same as DT[ x > 6.5 ]
anyString = quote(..thresh)
my_expr = bquote(g(col) > .(anyString))
DT[ eval(my_expr) ] # same as DT[ x > 6.5 ]
DT[ eval(my_expr), strict=TRUE] # error: symbol col is not a column name nor highlighted with ..
ĺĺăčĺĽăăăăăŤ@
ă使ç¨ăăŚiăŤĺä¸ăŽćĺĺăĺŤăăă¨ăăă˘ă¤ăă˘ăŻé常ăŤćčťă§ăăă ďźä¸ťčŚłçăŤďźé常ăŽdata.tableć§ćă¨ăŻĺ°ăç°čłŞăŤćăăžăă äťăŽăăă¤ăăŽĺ°ăăŞćŹ çšăŻăRăăľăăźăăăăłăźăă¨ăăŁăżă§ä˝ćĽăăŚăăă¨ăăŤăĺĺăŽăŞăźăăłăłăăŞăźăă¨č¤ć°čĄăŽĺźăŽčŞĺă¤ăłăăłăă夹ăăăăă¨ă§ăă
ăăăăŽćŹ çšăŻç˘şăăŤăăŹăźăăŞăăŽäžĄĺ¤ăăăăăăăăžăăăăçžćçšă§ç§ăčŚăŚăăăă1ă¤ăŽĺŽ˘čŚłçăŞăšăăźăăăłăăŻăĺä¸ăŽăˇăłăăŤ@
使ç¨ăăă¨ăăżăźă˛ăăéăŽăăăžăăăŽĺăćŠäźăćŽăĺŻč˝ć§ăăăăă¨ă§ăăĺ¤é¨ăŞăă¸ă§ăŻăăžăăŻdata.tableĺă
ăăă§ăŽć šćŹçăŞčŞ˛éĄăŽ1ă¤ăŻădata.tableăŽĺĺăăăžăŁăăç°ăŞăĺŽçžŠă§ĺ¤é¨ç°ĺ˘ă§ä˝żç¨ă§ăăăă¨ă§ăă ..
ăăŹăăŁăăŻăšăŻăć˘ĺăŽăĺĺăŽăŞăšăăćŠč˝ăŤăăăžăăăćŽăăžăăăăćŚĺżľăćĄĺźľăăŚăćŹć źçă§ć確ăŞé˘ć°ĺăăă°ăŠăăłă°ăĺŻč˝ăŤăăăŤăŻăĺ°ăŞăă¨ă1ă¤ăŽčż˝ĺ ăŽăăŹăăŁăăŻăšăĺż
čŚăŤăŞăĺ ´ĺăăăăžăă
@mattdowle䝼ä¸ăŤćŚčŞŹăăčăăăăĺăąăźăšă誏ćăăăăă¤ăăŽä˝żç¨äžăčż˝ĺ ăăăă¨ăŤăăă䝼ä¸ăŽčłŞĺăŤĺŻžĺŚăăăă¨ăăžăăă DT["<strong i="14">@A</strong> = ..."]
ăŽéăé˛ăăă¨ăŤăăĺ ´ĺăăăăă?
ă使ç¨ăăŚăĺĺă¨ăăŚčŠäžĄăăăăŻăăŽăăŽă¨ăăă§ăŞăăăŽăć確ăŤĺşĺĽă§ăăăăăŤăăăă¨ăŻăç§ăŽĺäşşçăŞĺ¸ćăŞăšăăŽä¸ä˝ăŤăăă¨ćăăžăă
ĺä¸ăŽăăźăăŤăŽăżă§ăŽćä˝ăŤă¤ăăŚčăăă¨ďźçľĺăŤăăăĺĺăŤăžăŁăăć°ăăć˝ĺ¨çăŞéč¤ăŽăťăăăĺ°ĺ ĽăăăžăăăăŽăšăłăźăă§ăăăčć Žăăĺż čŚăăăăăŠăăăŻăăăăžăăďź ăç§ďźăăăłăăăăäťăŽăŚăźăśăźďźăčăăăăăăă¤ăăŽćšćłăŽăŞăšăă揥ăŤç¤şăăžăăăăăžăăăéżăăăăăŤăăăžăăžăŞć˝ĺ¨çăŞăżăźă˛ăăăć示çăŤĺŽçžŠă§ăăăăăŤăăăă
ç§ăŤăŻă ..
ăŽä˝żç¨ćłăĺä¸ăŽĺďźăąăźăš3ďźăŤćĄĺźľăăăă¨ăŻç´ćçăŤç解ă§ăăĺăăăŹăăŁăăŻăšăćă¤ăąăźăš4ă6ăăăăł7ăĺŚçă§ăăăăăŤćăăăžăă 䝼ä¸ăŽäžă§ăŻăăăŹăăŁăăŻăšă¨ăăŚ..ext.
ă使ç¨ăăžăăăăăŻăĺĺăĺ¤é¨ç°ĺ˘ăŽĺ¤ă¨ăăŚčŠäžĄăăă DT
ĺ
ăŽĺă¨ăăŚčŠäžĄăăăŞăăă¨ă襨ăăžăă
|ăąăźăš| çžĺ¨ăŽăăŹăăŁăăŻăš| ć°ăăăăŹăăŁăăŻăš| ă§ä˝żç¨| ăżăźă˛ăă| ăżăźă˛ăăăŽčŞŹć
| --- | -------- | -------- | ---------- | -------- | ------- -|
| 1 | ăŞă| ăŞă| IăJăK | ăłăŠă | ćĺĺĺ|
| 2 | ăŞă| ăŞă| ç§ăJ | ĺ¤é¨| ăŞăăŠăŤĺ¤|
| 3 | | ..
| IăJăK | ăłăŠă | ĺ¤é¨ă§ĺŽçžŠăăăĺĺ|
| 4 | | ..ext.
| ç§ăJ | ĺ¤é¨| ĺ¤é¨ă§ĺŽçžŠăăăĺ¤ďźăžăăŻăăŻăăŤďź|
| 5 | ..
| ..
| JăK | ĺ| ĺ¤é¨ă§ĺŽçžŠăăăĺĺăŽăŞăšă|
| 6 | | ..ext.
| JăK | ĺ¤é¨| DTă§ä˝ćăăăĺ¤é¨ă§ĺŽçžŠăăăć°ăăĺăŽĺĺ|
| 7 | | ..ext.
| J | ĺ¤é¨| ĺ¤é¨ă§ĺŽçžŠăăăăDTă§ä˝ćăăăč¤ć°ăŽć°ăăĺăŽĺĺăŽăŞăšă|
# Case --------------------------------
# 1 2
DT[foo == "A"] # Cases 1 & 2: Literal column name, and a literal value
col = "foo" # Case 3: Column Name defined externally
val = "A" # Case 4: Value defined externally
# Case --------------------------------
# 3 4
DT[..col == ..ext.val] # DT[foo == "A"]
cols = c("foo","bar") # Case 5: List of column names defined externally
# Case --------------------------------
# 5
DT[, ..cols] # DT[, .(foo,bar)]
newcol = "nextday" # Case 6:Name of new column created in DT, defined externally
# Case --------------------------------
# 6 1 2
DT[, ..ext.newcol := day + 1] # DT[, nextday := day + 1]
newcols = c("nextday", "nextday2") # Case 7: List of names for multiple new columns created in DT, defined externally
# Case --------------------------------
# 7 1 2 1 2
DT[, ..ext.newcols := .(day + 1, day + 2)] # DT[, c("nextday", "nextday2") := .(day + 1, day + 2)]
## Putting it all together (in a totally nonsensical way for illustration only)
col = "foo"
col2 = "bar"
col3 = "day"
newgroup = "baz"
val = "A"
val2 = 1
newcols = c("nextday", "fooday")
printcols = c("baz","nextday","fooday")
# Case -------------------------------------------------------------------------------------------------------------
# 3 4 7 3 4 3 3 6 3 5
DT[..col == ..ext.val, ..ext.newcols := .(..col3 + ..ext.val2, paste0(..col, ..col3)), by = .(..ext.newgroup = ..col2)][, ..printcols]
#DT[foo == "A", c("nextday", "fooday") := .(day + 1, paste0(foo, day)), by = .(baz = bar)][,.(baz, nextday, fooday)]
ç§ăç解ăăŚăăăă¨ăăăăăŹăăŁăăŻăšč¨ĺˇăŻăăźăšRă§ćĺšăŞăŞăă¸ă§ăŻăĺă¨ăăŚč§ŁćăăăăăŽăŤĺśéăăăŚăăžăăďź ăăăăăŞăăăąăźăš4ă6ă7ăăŤăăźăăăăă¤ăăŽăŞăăˇă§ăłăŻ._col
ă .._col
ă ..ext.col
ăăăăăžăăăăăăăăŽăŠăă..
ăăăŤćĺ
ăăćľăĺşăžăă...
ăŻçčŤçăŤăŻćŠč˝ăăăăăăăžăăăă ..
ă¨...
ăĺşĺĽăăăă¨ăăă¨ăäťăŽä˝ăăăçé çăĺ˘ăăăăă§ăă
äťăŽäşşăăťăŽăăăăŚăăăăăŤăĺ¤é¨ç°ĺ˘ă§ĺŽçžŠăăăă¨ăăŤĺĺďźăąăźăš3ă¨6ďźăĺźç¨ăăăĺ ´ĺăăąăźăš3ă7ăŽăăšăŚăŽĺä¸ăŽăăŹăăŁăăŻăšăćŠč˝ăăĺŻč˝ć§ăăăăăă§ăă ăăŹăźă ăŻăźăŻăŤç˛žéăăŚăăŞăăŽă§ăĺăč¨č¨ä¸ăŽćąşĺŽăŽăăă¤ăăăăă§ć˝ĺ¨çăŤĺ˝šçŤă¤ăăŠăăă確čŞăăăăăŤăăăĺ°ăčŞăă§ăżăžăă ć´ć°ďź rlang
ă¨tidyeval
čŞăă ăŽă§ăăăäťăŻćˇˇäšąăăŚăăžăă
ăă税ăŽstrict = TRUE
ăŞăăˇă§ăłă使ç¨ăăă¨ăăă˘ă¤ăă˘ăŻăĺ°ć°ăŽä¸ç´ăŚăźăśăźădata.tableăŞăă¸ă§ăŻăăćä˝ăăé˘ć°ăăĺĺżč
ăŤé庌ăŽč˛ ć
ăăăăăŤăăăé˛ĺžĄçăŤč¨čż°ă§ăăăăăŤăăăŽăŤĺ˝šçŤă¤ĺŻč˝ć§ăăăăăă§ăăć°ăăć§ćă¨ăăŹăăŁăăŻăšăŽćă
ăłăĄăłăăä¸ăăé çŞăŤčŚăŚăăăžăăăďź
[1ć] @ăŽäťŁăăăŤ1ă¤ăŽćĺĺă使ç¨ăăă¨ăăă˘ă¤ăă˘ăŻĺĽ˝ăă§ăŻăăăžăăă ăŚăźăśăźăŻbquoteă使ç¨ăăŚĺźăŽĺ¤ć°ăç°ĄĺăŤç˝Žăćăăăă¨ăă§ăăăăăŻăăĺşćŹçăŞRăŽćšćłăŤă¨ăŠăžăăžăă ć°ăăăŤăšăżă č¨č¨ăăăłäżĺŽăăăAPIăŻăăăžăăă
ăăăSăŽäžă§bquote
ă使ç¨ăăăŽăăăăŤç°Ąĺă§ăăăăŽäžă示ăăŚăăă ăăžăăďź
[1ć]ăăă°ăŠă ăŽčŚłçšăăăăŚăźăśăźăŻ1ă¤ăŽéˇăćĺĺăä˝ćăăăăă
DT[i=.
渥ăĺż čŚăăăăžăă
ĺŽéăĺ¤ć°ăĺż
čŚăŤăŞăăăăćĺĺă渥ăăă¨ăŻă§ăăžăăă i
ăŽĺ¤ć°ăŻăä˝ăéăăă¨ăćĺłăăžăă ćĺĺăŻ[...]
ĺ
ăŤčĄ¨ç¤şăăăĺż
čŚăăăăžă; ă¤ăžăăćĺéăDT ["..."]ă ăăŽĺ ´ĺă substitute(i)
ăżă¤ăăŻcharacter
ă§ăăăăăăăăŻRă§ĺşĺĽă§ăăžăă
[1ć]ăăăťăŠĺ ç˘ă§ăŻăăăžăăă
čĺźąć§ăŽä¸äžăćăăŚăăă ăăă°ăç解ă§ăăžăă
[1ć]ăŞăšăăĺăĺ Ľăăă°ăăăă°ăŠă çăŤăŻăăăŤä˝żăăăăăŞăăćçľçăŤăŻďź1579ďźăłăĄăłăďźăŤäźźăăăŽăŤăŞăăžăă
ç§ăŻéĺťăŤdata.tableăŽăŚăźăśăźă§ăăŁăă¨ăăŤăăăŽăăăŞăăă°ăŠă çăŞăă¨ăăăžăăă ăăăăćŁç´ăŞă¨ăăăç§ăŻăăăćŹĺ˝ăŤĺĽ˝ăă§ăŻăăăžăăă§ăăă quote()
ăžăăŻbquote()
ďźăŠăĄăăďźăŻäşĺăŤč¨ĺŽăăĺż
čŚăăăăăăŠăĄăźăżĺ
¨ä˝ăăăăăŽăăăăă§ä˝ćăăĺż
čŚăăăăžăăăăăă¨ăquote()
ă§ä˝ćă§ăăžăăďźăžăăŻbquote()
j=
ĺźăŽä¸é¨ă§ä˝żç¨ăăžăăďź ĺ°ăŞăă¨ăç§ăŽçŽăŤăŻĺŞăăăăŽă§ăŻăăăžăăă ăăŽăăŻăăŽă˘ă¤ăă˘ăŻă誏ćăăăŽăç°Ąĺă§ăç°Ąĺă§ăăăăžăăă§ăăă ĺäşşçăŤăŻăç§ăććĄăăăăŽďźĺç´ăŞăăźăŻăłăŽç˝Žăćăďźă使ç¨ăăžăă
[1ć]ĺŞĺ 庌ăéŤăăŞăĺ ´ĺăŻăă¨ăăăăăăŽăžăžăŤăăŚăăăžăăăă
..
ăăŹăăŁăăŻăšăćĄĺźľăăŚă j=
ĺ
ăŽăăšăŚăŽăˇăłăăŤă§ćŠč˝ăăăăăŤăăăăă§ăă ăăŽ..
ăééăă§ăăĺ ´ĺăŻăăăă解ćžăăŚăăăŻăăĺăŤăäťăăăăă確çŤăăĺż
čŚăăăăžăă ĺžă§ĺ
ăŤćťăăŽăŻéŁăăăŞăăžăă ĺĽăŽăăŹăăŁăăŻăšăĺż
čŚăŞĺ ´ĺăŻăäťăăćąşĺŽăăŚăćşčśłăŽăăĺŽĺ
¨ăŞč¨çťăçŤăŚăĺż
čŚăăăăžăăçľĺąă ..
ćąşĺŽăăŚăăŞăăŁăă¨čăăăăăăă§ăă
[çç´]ç§ăŻăćĺĺăăăĺźă弽ăJanăŤĺćăăžăă
Janăä¸č¨ăŽçšăŤĺçăăĺžăăăä¸ĺşŚčŚăŚăżăžăăăă
[ăăŠăłăŻ] get / mgetăŽăăăŞé˘ć°ăčż˝ĺ ăăžăăăăăăŻdata.tableăŽĺăŽéă§ăŽăżčĄ¨ç¤şăăăžă
ĺéĄăŻăăăăĺ
é¨ă§ăŠăŽăăăŤĺŚçăăăă§ăă j=
ăă°ăŤăźăăă¨ăŤĺŽčĄăăăŚăăăă°ăŤăźăăăăăăăăă¨ăăžăă g()
ăçĄé§ăŤä˝ĺşŚăĺŽčĄăăăăŻăăăžăăăćŻĺĺăĺăĺĺžăăă ăă§ăďźăŻă¨ăŞăéĺ§ăăăĺăŤ1ĺĺŽçžŠăăăŚăăžăďźă ăăăăŁăŚă g()
ăă°ăŤăźăăŤĺżăăŚç°ăŞăĺăčżăĺŻč˝ć§ăăăăăŠăăăĺ
é¨ă§ç˘şčŞăăĺż
čŚăăăăžăăăăă§ăŞăĺ ´ĺăŻăăăăĺăăŁăŚĺăĺşăăŚćéŠĺăăĺŽć°ăŤăŞăăăăŤăăžăă ăăăŤăŻă g()
ĺźăłĺşăăĺŽć°ăŤç˝Žăćăăăă¨ăĺŤăžăăžăă ăăăŻăăšăŚé˘ĺă§ă¨ăŠăźăçşçăăăăă§ăă mget
ăăăšăŚăŽĺăĺźăłĺşăăŚ.SD
ĺĺ¨ăăççąăŽä¸é¨ăŻăăăŽăăăŞăăŽăŤăăăăŽă§ăă ăăăŻĺŽčĄĺŻč˝ă§ăăăéŁăăă§ăă
ăăźăŻăłăŽç˝Žćă弽ăăŞăŽăŻăăăă揥ăŽăăăŤč¨ăăă¨ăă§ăăć示çăŞć§ćă ăăă§ă...ăăăăžăăăăăŽăŻă¨ăŞăŻăăă°ăŠă ă§ăăăäşĺăŤăăă°ăŠă ă§ä¸ĺşŚĺŽçžŠăăăŚăăžăă ăăŽĺžăé常ăŽăŻă¨ăŞă¨ăžăŁăăĺăăăăŤĺŽčĄăăăžăă ç§ăŽčŚč§Łă§ăŻăăăăŻçăŤăăŞăŁăŚăăăă¨ăŻćăăă§ăă ăă¸ăăŻăŻć確ăŤĺé˘ăăăŚăăžăăiďźĺŽčĄăăăŻă¨ăŞăĺŽçžŠăăćĺăŽăšăăăă揥ăŤiiďźăŻă¨ăŞăĺŽčĄăăžăă gďźďźăevalďźďźăbquoteďźďźăŞăŠăăăĺ ´ĺăăăăăŻĺ é¨ĺ ¨ä˝ă§ĺŽčĄăăăĺ°éŁăŤăŞăăžăă EVAL = parseďźtext = pasteďź...ďźďźă˘ăăăźăă弽ăă§ăć¨ĺĽ¨ăăççąăä¸ĺşŚć¸ăăăă¨ăčŚăăŚăăžăăăăăŻăé常ăŽĺç´ăŞăŻă¨ăŞăćĺăŤĺ Ľĺăăĺ ´ĺă¨ĺăăăăŤăăŻă¨ăŞăăăăăŤćéŠĺă§ăăăăă§ăă
[ăăăS]ĺĺăčĺĽăăăăăŤ@ă使ç¨ăăŚiăŤĺä¸ăŽćĺĺăĺŤăăă¨ăăă˘ă¤ăă˘ăŻé常ăŤćčťă§ăăăďźä¸ťčŚłçăŤďźé常ăŽdata.tableć§ćă¨ăŻĺ°ăç°čłŞăŤćăăžăă
NSă ć°ĺĺŻăĺžăăç§ăŻăžă ăăă弽ăă§ăă ăăŽĺ ´ĺăŽăé常ăăŻbquoteăevalăŞăŠă使ç¨ăăŚăăăăăăé常ăăŽdata.tableć§ćăŤăŻăăŽćŠč˝ăăŞăăăăćŻčźăăĺż čŚăăăăžăă
[ăăăS]äťăŽăăă¤ăăŽĺ°ăăŞćŹ çšăŻăRăăľăăźăăăăłăźăă¨ăăŁăżăźă§ä˝ćĽăăŚăăă¨ăăŤăĺĺăŽăŞăźăăłăłăăŞăźăă¨č¤ć°čĄăŽĺźăŽčŞĺă¤ăłăăłăă夹ăăăăă¨ă§ăă
ăĄăżăŻă¨ăŞăä˝ćăăă¨ăăŻăăăăăŽăă¨ăŻă¨ăŤăăćŠč˝ăăžăăďźä˝żç¨ăăăĺĺăŻćčťăŤĺŽçžŠăăăăăďźăăăăăŁăŚăăăăŻćĺĺăŞăăŠăŤă使ç¨ăăŚăăăăăă¨ăăŁăżăźă§č˛ăç°ăŞăăăăçŽçŤă¤ăăăŤăŞăŁăŚăăă¨ăăă§ăăăă äžă示ăç§ăŽăłăĄăłăă§ä¸č¨ăŽGitHubăŽč˛ăčŚăŚăăăă§ăŤç§ăŽçŽăŤăŻăăŞăăăčŚăăžăă ăĄăżăŻă¨ăŞăŻéč˛ă§çŽçŤăĄăĺźç¨çŹŚă§ĺ˛ăžăăŚăăžăăăĺźăłĺşăăšăłăźăăŽĺŽéăŽĺ¤ć°ăŻăŞăŹăłă¸č˛ă§ĺźˇčŞżčĄ¨ç¤şăăăŚăăžăă ç§ăŽă¨ăăŁăżăźă§ăăăźăŤăŤă§ĺăăăăŤčŚăăžăă
ç§ăŻăăŞăăŽăłăĄăłăăŽćŽăăŽĺ¤ăăăăŠăăźăăŚăăžăăă ĺŽéăŽăłăźăäžăčŚăĺż čŚăăăăžăă ăă¨ăă°ăăĺ¤é¨ăăŽćĺłă100ďź ć確ă§ăŻăŞăăăăăăŽăăźăăŤăăłăźăăŤĺ¤ćă§ăăžăăă
[Matt S]ăă税ăŽstrict = TRUEăŞăăˇă§ăłă使ç¨ăăă¨ăăă˘ă¤ăă˘ăŻăĺ°ć°ăŽä¸ç´ăŚăźăśăźădata.tableăŞăă¸ă§ăŻăăăăé˛ĺžĄçăŤćä˝ăăé˘ć°ăăĺĺżč ăŤç解ăŽĺż čŚć§ăé庌ăŤč˛ ć ăăăăă¨ăŞăč¨čż°ă§ăăăăăŤăăăŽăŤĺ˝šçŤă¤ĺŻč˝ć§ăăăăăă§ăăăăăăăŽć°ăăć§ćă¨ăăŹăăŁăăŻăšă
ăŻăă ăăŽă˘ă¤ăă˘ăŻé渥çăŞăăŽă§ăăăăăžăăăă°ć°ĺš´ĺžăstrict = TRUEă常ăŤĺ˝ăŚăŻăžăăăŞăăˇă§ăłă§ăŻăăăžăăă ăă ăăä¸ç´ăŚăźăśăźă ăăŽăăŽă§ăŻăăăžăăă ĺŽéăăăŽéă§ăă ä¸ç´č
䝼ĺ¤ăŽăŚăźăśăźăŤăăäşć
ăé˛ăăăă§ăă ĺĺżč
ăŻăĺźăłĺşăăšăłăźăăŤĺ°éăăăăăŤ..
ăăŹăăŁăăŻăšă使ç¨ăăĺż
čŚăăăăžăă 彟ăăŻăć°ăăé˘ć°ăĺŤăăăŽăăăăăĄăżăŻă¨ăŞăććĄăăăăďźçľĺąăŽă¨ăăăćĺĺăŽç˝ŽćăŤăăăŞăďźă¨ćăă§ăăăă ç§ăăăă§ăăă彟ăăŻquote
/ bquote
/ enquote
ăăšăŚăé常ăŤćˇˇäšąăăŚăăă¨ćăăŚăăžăă ă¨ăŠăźăĄăăťăźă¸ăŻăĺĺżč
ăĺżľé ăŤç˝ŽăăŚé常ăŤĺ˝šçŤăĄăžăďźäžďź "'coef' is not a column name, but it is in calling scope. Please add the prefix '..' to coef to make it clear so it won't ever break in future if you ever add a column called coef."
ăăă§ăŻăăăăSăŽäžă§bquoteă使ç¨ăăăŽăăăăŤç°Ąĺă§ăăăăŽäžă示ăăŚăăă ăăžăăďź
ĺŽéăŤăŻĺźç¨ă§ăŻăŞăă䝼ä¸ăŽč¨čŞă˝ăŞăĽăźăˇă§ăłă§ăă
čĺźąć§ăŽä¸äžăćăăŚăăă ăăă°ăç解ă§ăăžăă
ăăŽă˝ăŞăĽăźăˇă§ăłăŤăŻčĺźąć§ăŻăăăžăăăăćĺĺźăŤăăDTăŽăŻă¨ăŞăŻăeval-parseăŤăăŁăŚéŠĺăŤĺŚçăăăžăă
č¨čŞă¨ćĺĺăŽă˝ăŞăĽăźăˇă§ăłăăŠăăĺŽéăŤăŻăŚăźăśăźăăŹăłăăŞăźă§ăŻăăăžăăăă埡ĺă§ăăźăšRă§ăăăĺŽĺŽăăŚăăŚăć確ăŤĺŽçžŠăăăăăšăăăăAPIă§ăă
ç§ăŻăăŚăźăśăźăŽäžżĺŽăŽăăăŤăăăć¸ăăăăŽăăéăćšćłăćă¤ăă¨ăçăŤăăŞăŁăŚăăăă¨ăŤĺćăăžăă ăăă§ăăćŹçŞăłăźăăŽĺ ´ĺăć§ćăŽĺĽĺ
¨ć§ăă§ăăŻăčż˝ĺ ăăăăăăćĺĺăćä˝ăăăŽă§ăŻăŞăăĺźăłĺşăăä˝ćăăžăă
library(data.table)
set.seed(1234)
DT <- data.table(foo = rep(LETTERS[1:2],8),
bar = rep(letters[17:20],4),
month = rep(month.name[1:4],4),
day = seq_len(16),
yyy = rnorm(16,mean = 0.5,1.5))
## Expression 1: with hard coded columns
DT[yyy > 0,.(NewCol = paste(month, day),
bar,
yyy), by = foo] -> ans
## Expression 2: everything passed by reference
A = "yyy"
B = 0
C = "NewCol"
D = "month"
E = "day"
G = "foo"
H = c("bar","yyy")
#DT[..A > ..B , .(..C = paste(..D, ..E),
# ..H), by = ..G]
# foo NewCol bar yyy
"# ---- language ----"
qc = as.call(list(
as.name("["),
x = quote(DT),
i = call(">", as.name(A), B),
j = as.call(c(list(as.name(".")), setNames(list(call("paste", as.name(D), as.name(E))), C), lapply(H, as.name))),
by = as.name(G)
))
eval(qc) -> ans2
"# ---- string ----"
ci = paste(A, B, sep=" > ")
cj = paste0(".(", C, " = paste(", D, ", ", E, "), ", paste(H,collapse=", "),")")
cby = paste0("list(", G, ")") # this could be simplified
DT[eval(parse(text=ci)), eval(parse(text=cj)), by = eval(parse(text=cby))] -> ans3
# another
cdt = paste0("DT[", paste(c(ci, cj, cby), collapse=","), "]")
eval(parse(text=cdt)) -> ans4
identical(ans, ans2) # T
identical(ans, ans3) # T
identical(ans, ans4) # T
ĺŽéăŤç§ăŤă¨ăŁăŚăăĺ
ąéł´ăăŚăăăăăŤčŚăăăŽăŻă @vars
罎ăćăăăă¨ăŤăăćĺĺć§çŻăŽăăŤăăźé˘ć°ă§ăă [
ĺźăłĺşăăăçŹçŤăăŚăăžăă 揥ăŤăăć°ăăapiăăćĺ°éăŤĺśéăăć§çŻăăăćĺĺăeval-parseăăă ăăŤăăžăă ăăăăŁăŚăăăăä˝ćăăăă¨ăŻăăăŽäžă§ăŻćĺĺăŽäťŁăăăŤč¨čŞăŞăă¸ă§ăŻăă使ç¨ăăăăŻăććĄăŤĺŻžĺżăăćŠč˝ă§ăă
query = helper("<strong i="19">@A</strong> > <strong i="20">@B</strong>, .(<strong i="21">@C</strong> = paste(<strong i="22">@D</strong>, @E), @H), @G")
DT[text = query]
# or alternative api
DT[~query]
ăŠăĄăăŽĺ ´ĺăăăăŻćăăă§ăŻăŞăăŽă§ćł¨ćăĺż
čŚăăăăăžăă@H
ă§ăŞăăă°ăŞăăžăăunlist
1ă¤ăŽăŞăšăăŤăăźă¸ăă硨ă§@C
ă¨ăăŚăăăăăŻćťĺ¨c("bar","yyy")
/ .(bar, yyy)
ă
i
ă§ăăăŤĺ¤ăăŽç¨ŽéĄăŽĺźăłĺşăăĺŚçăăăă¨ăŻéżăăăă¨ćăăžăăčŚăçŽăŻç´ ć´ăăăăˇăłăăŤă§ăăăăăăĽăĄăłăăŤć°ăăif
ăčż˝ĺ ăăăžăă
j =ăŽăăšăŚăŽăˇăłăăŤă§ćŠč˝ăăăăăŤ..ăăŹăăŁăăŻăšăćĄĺźľăăă°ăăă ăăă§ăă ăăăééăă§ăăĺ ´ĺăŻăăăă解ćžăăŚăăăŻăăĺăŤăäťăăăăă確çŤăăĺż čŚăăăăžăă ĺžă§ĺ ăŤćťăăŽăŻéŁăăăŞăăžăă ĺĽăŽăăŹăăŁăăŻăšăĺż čŚăŞĺ ´ĺăŻăäťăăćąşĺŽăăŚăćşčśłăŽăăĺŽĺ ¨ăŞč¨çťăçŤăŚăĺż čŚăăăăžăăçľĺąăćąşĺŽăăŚăăŞăăŁăă¨čăăăăăăă§ăă
ĺć
[Matt Dowleďź]ăăăăŁăŚă
g()
ăă°ăŤăźăăŤĺżăăŚç°ăŞăĺăčżăĺŻč˝ć§ăăăăăŠăăăĺ é¨ă§ç˘şčŞăăĺż čŚăăăăžăăăăă§ăŞăĺ ´ĺăŻăăăăĺăăŁăŚĺăĺşăăŚćéŠĺăăăă¨ă§ăĺŽć°ăŤăŞăăžăă ăăăŤăŻăg()
ĺźăłĺşăăĺŽć°ăŤç˝Žăćăăăă¨ăĺŤăžăăžăă ăăăŻăăšăŚé˘ĺă§ă¨ăŠăźăçşçăăăăă§ăămget
ăăăšăŚăŽĺăĺźăłĺşăăŚ.SD
ĺĺ¨ăăççąăŽä¸é¨ăŻăăăŽăăăŞăăŽăŤăăăăŽă§ăă ăăăŻĺŽčĄĺŻč˝ă§ăăăéŁăăă§ăă
[...]
ăă¸ăăŻăŻć確ăŤĺé˘ăăăŚăăžăăiďźĺŽčĄăăăŻă¨ăŞăĺŽçžŠăăćĺăŽăšăăăă揥ăŤiiďźăŻă¨ăŞăĺŽčĄăăžăă gďźďźăevalďźďźăbquoteďźďźăŞăŠăăăĺ ´ĺăăăăăŻĺ é¨ĺ ¨ä˝ă§ĺŽčĄăăăĺ°éŁăŤăŞăăžăă
čżäżĄăăăă¨ăăăăăžăă ăăăŻçăŤăăŞăŁăŚăăă ç§ăŻă g()
ăăéŠĺăŞé˘ć°ă§ăŻăŞăă list
ăŤăŞă.
ă¨ĺć§ăŤăăšăăăďźiďźă§ç˝ŽćăăăŞăŹăźăăăăźăŻă˘ăăă§ăăă¨ćłĺăăŚăăžăăă ăăăŚăĺŻä¸ăŽĺźć°ă¨ăăŚăŽăăăŞćĺĺ1ă¤ăŽăŹăăŤăžă§ăŽăăŹăăŁăăŻăšĺ¤ć°ăă¤ăłăăŁăłă°ă訹ĺŻg(..v)
ăŤăŞăă¨ćăăăă x
ăžăăŻ.(x = x, y = y)
ăă§ĺć§ăŽj
ă罎ćă示ă芳細ăĄăăťăźă¸äťăă
@ăăŹăăŁăăŻăšăŤĺŻžăă1ă¤ăŽç°č°ăŻăĺä¸ĺ¤ć°ăŽăŚăźăšăąăźăšăăŤăăźăăăăă ăăŤč¨č¨ăăăŚăăăăăŤčŚăăăă¨ă§ăă .SDcols
ăľăăťăăă§ăŻăŞăĺăŽăăŻăăŤă渥ăăăĺ ´ĺăŻăŠăăŞăăžăăďź ďźăľăăťăăăŽĺ ´ĺăĺ°ăŞăă¨ă.SD[, ..v]
ăĺŽčĄă§ăăžăăďź
ç§ăŽäťăŽç°č°ăŻăJanăčż°ăšăăă¨ă§ăăăăăă§ăăćŹçŞăłăźăăŽĺ ´ĺăć§ćăŽĺĽĺ ¨ć§ăă§ăăŻăčż˝ĺ ăăăăăăćĺĺăćä˝ăăăŽă§ăŻăŞăăĺźăłĺşăăä˝ćăăžăăă ćĺĺĺ ăŤăłăźăăć¸ăăŽă§ăŻăŞăăăłăźăăăłăźăă¨ăăŚć¸ăăă¨ăŤäź´ăRăŽć§ćăă§ăăŻă弽ăă§ăă ăăăŚăćŹçŞăłăźăăŽĺ ´ĺăćĺĺăŤć¸ăčžźăă ăłăźăăŻćŹĺ˝ăŤäżĄç¨ă§ăăŞăă¨ćăăžăă
ĺăă˘ă¤ăă˘ăŽĺĽăŽăăŞă¨ăźăˇă§ăłďź .SDcols
ďźăžăăŻäťăŽĺźć°ďźăćĄĺźľăăŚă罎ćăăĺé¸ćĺźăŽăŞăšăăăľăăźăăăžăă
library(data.table)
DT = data.table(mtcars)
z = "newcol"
DT[, .(..z = sum(..x + ..y), lapply(.SD, max)), by=am,
.SDcols = list(disp:drat, x = "wt", y = "qsec")]
# substitutes j before evaluation to become...
# list(newcol = sum(wt + qsec), disp = max(disp), hp = max(hp), drat = max(drat))
ăăăăŁăŚăăăŽäťăŽĺźć°ă§..x
ă¨..y
ăćĺăŤDT[...]
ăŤć¤ç´˘ăďźĺŽéăŤ1ăŹăăŤä¸ăć¤ç´˘ăăĺăŤďźăé˘éŁăăĺăŤç˝Žăćăăžăă
JanăŻăăăăăăăŤăăăăă§ăăăŤăăźă¨ăăŚă§ăŻăăăžăăă@ăăźăŻăłăŽç˝ŽćăŤă¤ăăŚĺćăăŚăăžăă ďźăăăăŽquoteďźďźăcallďźďźăăăăłas.callďźďźăŻăăŚăźăśăźăŻăăĄăăăŽăă¨ăăăšăŚç§ăŤă¨ăŁăŚĺ¤§ĺ¤ăŞä˝ćĽă§ăăďź@ăăźăŻăłăŻăĺźăłĺşăăšăłăźăăĺćĺăăăăłéˇă1ăŽĺ¤ć°ă§ăăăăŠăăăăă§ăăŻăăăžăďźăăă§ăŞăĺ ´ĺăŻă¨ăŠăźďź ďźă ăăăĽăĄăłăă¸ăŽăă1ă¤ăŽăifăăŻăăŞăčŻăă¨ćăăžăă ăăăŻăĄăżăŻă¨ăŞăä˝ă§ăăăă誏ćăăă§ăăăăăăăŚăăăŻç°Ąĺă§ăă 桡䚹ăăă°ăŹăăźăă確çŤăăăŚăă䝣ćżćĄă誏ćăăăăăăŻăăăŤç°Ąĺă§ăă ăĄăżăŻă¨ăŞăĺŤăĺ¤ć°ă渥ăăŞăççąăŻăăăăăăăăăŤăăăĄăżăŻă¨ăŞă§ăăăă¨ăć確ăŤăăăăă§ăă ăăăăĄăżăŻă¨ăŞă§ăăăăŠăăăŻăăłăźăăŽä¸ä˝ă§ĺŽçžŠăăăŚăăăă渥ăăăĺ¤ć°ăŤäžĺăăĺż čŚăŻăăăžăăăăĄăżăŻă¨ăŞăŽăăăŤčŚăăăŻăă§ăă
ăăŠăłăŻ-ăăăăžăăăgďźďźăŤă¤ăăŚăŽăăŞăăŽčăăăăăăžăăă ăă ăăgďźďźă罎ćăăĺ ´ĺăŻăăăźăŻăłç˝Žćă使ç¨ăăăă¨ăă§ăăžăă ăăŽăăăŞăłăźăăŽčŞč ăŻăgďźďźă¨ăŻä˝ăăăăăŚăăăä˝ăăăăăçĽăĺż čŚăăăăžăă ăĄăżăŻă¨ăŞă˘ăźăăăăć確ăŤç¤şăăŤăŻăăŤăăŻă˘ăłăăăŁăźăŤăăăĺçăŤĺăćżăăĺż čŚăăăă¨ćăăžăă
@ăăŹăăŁăăŻăšăŤĺŻžăă1ă¤ăŽç°č°ăŻăĺä¸ĺ¤ć°ăŽăŚăźăšăąăźăšăăŤăăźăăăăă ăăŤč¨č¨ăăăŚăăăăăŤčŚăăăă¨ă§ăă
ăăăŻä˝ă§ăăŤăăźăăăăăŤč¨č¨ăăăŚăăžăă ĺŽĺ ¨ăŤćčťă data.tableăŻă¨ăŞăä˝ćăăăăăŽĺç´ăŞăăźăŻăłç˝Žćă 芳細ă˘ăźăă§ăŻăä˝ćăăăăŻă¨ăŞăĺşĺăăăžăă ăăŽăŻă¨ăŞă解ćăăăŞăĺ ´ĺă§ăăRăŻăăăăăŁăăăăžăă ăăăăĺŽčĄćăŤă ă¨ăŤăăĺż čŚăŞăŽăŻăăă§ăă ăăăŻĺçăŻă¨ăŞă§ăă
.SDcolsăŽăľăăťăăă§ăŻăŞăĺăŽăăŻăăŤă渥ăăăĺ ´ĺăŻăŠăăŞăăžăăďź ďźăľăăťăăăŽĺ ´ĺăĺ°ăŞăă¨ă.SD [ă.. v]ăĺŽčĄă§ăăžăăďź
ĺŽĺ ¨ăŞäžăŻä˝ă§ăăďźăăă調ăšăŚăżăžăăăă
ç§ăŽäťăŽç°č°ăŻăJanăčż°ăšăăă¨ă§ăăăăăă§ăăćŹçŞăłăźăăŽĺ ´ĺăć§ćăŽĺĽĺ ¨ć§ăă§ăăŻăčż˝ĺ ăăăăăăćĺĺăćä˝ăăăŽă§ăŻăŞăăĺźăłĺşăăä˝ćăăžăăă ćĺĺĺ ăŤăłăźăăć¸ăăŽă§ăŻăŞăăăłăźăăăłăźăă¨ăăŚć¸ăăă¨ăŤäź´ăRăŽć§ćăă§ăăŻă弽ăă§ăă ăăăŚăćŹçŞăłăźăăŽĺ ´ĺăćĺĺăŤć¸ăčžźăă ăłăźăăŻćŹĺ˝ăŤäżĄç¨ă§ăăŞăă¨ćăăžăă
quote
ă bquote
ă as.call
ă call
ăŞăŠăŽé˘ć°ďźJană彟ăŽăłăĄăłăăŻăç§ăćŹçŞç°ĺ˘ăŤéŠăăŞăă¨čăăŚăăžăăďźăăăăŻăć¸ăăŽăăăăăă°ăăăŽăăçśćăăăŽăéŁăăă§ăă ç§ăŽčŚč§Łă§ăŻăăăźăŻăłç˝ŽććšćłăŻăăĺç´ă§ăăăăăăăŁăŚĺŽéăŤăŻćŹçŞçŽçă§ăăĺ
ç˘ă§ăă ăă¨ăă°ăćŹçŞç°ĺ˘ă§ĺŽčĄăăăĺŽéăŽăŻă¨ăŞăŻăă°ăăĄă¤ăŤăŤć¸ăčžźăžăăăăďźevalďźďźăbquoteďźďźăcallďźďźăŞăŠăĺŤăžăăŞăăăă誰ă§ăčŞăżĺăăă¨ăă§ăăžăďźăćŹçŞç°ĺ˘ăŤăă°ă¤ăłăăćšăĺ
ç˘ă§ăă ă ç§ăŻççŁăˇăšăă ăŤé˘ăăŚĺ¤ăăŽçľé¨ăćăŁăŚăăžăă ç§ăŻ20䝣ĺĺăŽă¨ăăŤăăŞăźăăłăăŠăśăźăşăŽĺĺźăˇăšăă ăĺćĽĺć˘ăă貏䝝ăăăăžăăă ç§ăŻăăłăłăăăźăŤă硊ăăăăŤćťăă 食ćăčŚéăăăăŚăăžăă¨ăăçľé¨ăăăăăćăŁăŚăăžăă ççŁăŽćĺŞĺ
ăŽçŽć¨ăŻĺç´ăă§ăă ćŻčťăĺ°ăŞăăťăŠčŻăă§ăă äžĺé˘äżăĺ°ăŞăăťăŠčŻăă§ăă ĺç´ăŞăłăźăăŻă常ăŤăăč¤éăŞăłăźăăăăĺŞĺ
ăăăžăă callďźďźăas.callďźďźăbquoteďźďźăŞăŠăŽăăšăŚăŽĺźăłĺşăăčĄăŁăŚăăăŽăŻăă¨ăŤăăĺçăŻă¨ăŞăä˝ćăăăă¨ă§ăă ăŻăăRăŻăăăăä˝ćăăă¨ăăŤăăăăăŽć§é ăćĺšăŞRă§ăăăă¨ă確čŞăăŚăăžăăăĺçăŻă¨ăŞă§ăăăăçľăżĺăăăăŚä¸çˇăŤä˝żç¨ăăăăŽăŻĺŽčĄćă§ăďźăăăŚăăăăĺŁăăăăăăăžăăďźăĺçăŻă¨ăŞăćŹçŞç°ĺ˘ă§ĺŁăăĺ ´ĺă揥ăŤă quote
ă call
ă bquote
桡䚹ăăăăă°ăăăŽă§ăŻăŞăăĺŽčĄăăăăŻă¨ăŞăéçĽăăăĄăżăŻă¨ăŞăĺŚçăăăă¨ćăăžăăĺźăłĺşăăžăă
[ç§ďź]ăSDcolsăŽăľăăťăăă§ăŻăŞăĺăŽăăŻăăŤă渥ăăăĺ ´ĺăŻăŠăăŞăăžăăďź ďźăľăăťăăăŽĺ ´ĺăĺ°ăŞăă¨ă.SD [ă.. v]ăĺŽčĄă§ăăžăăďź
[Matt Dowleďź]ĺŽĺ ¨ăŞäžăćăăŚăă ăăăăăă調ăšăŚăżăžăăăă
ăă¨ăă°ăĺ¤ć°ăŽč¤ć°ăŽă°ăŤăźăăčŚç´ăăăăă°ăŠă ă§ĺ Ľĺĺăé¸ćăăĺşĺĺăŤĺĺăäťăăăă¨ăčăăŚăăžăă
library(data.table)
DT = data.table(mtcars)
min_em = c("disp", "hp")
min_em_prefix = "min"
mean_em = c("drat", "wt")
mean_em_prefix = "mean"
max_it = "qsec"
max_it_name = "mymax"
by_em = "am"
# goal query
DT[, .(
min.disp = min(disp), min.hp = min(hp),
mean.drat = mean(drat), mean.wt = mean(wt),
mymax = max(qsec)
), by=am ]
# current syntax
# with four warnings since ..min_em and ..mean_em already up one level relative to .SD[...], i guess
DT[, c(
{z <- lapply(.SD[, ..min_em], min); setNames(z, sprintf("%s.%s", ..min_em_prefix, names(z)))},
{z <- lapply(.SD[, ..mean_em], mean); setNames(z, sprintf("%s.%s", ..mean_em_prefix, names(z)))},
setNames(max(.SD[[..max_it]]), ..max_it_name)
), by=by_em]
# proposed syntax?
DT[, "c(
..min_em_prefix = lapply(<strong i="10">@min_em</strong>, min),
..mean_em_prefix = lapply(<strong i="11">@mean_em</strong>, mean),
..max_it_name = max(@max_it)
)", by="..by_em"]
ăăăăŁăŚăăăă§ăŽă@ăăŻă2ă¤ăŽç°ăŞăăżă¤ăăŽç˝ŽćăčĄăŁăŚăăžăă
@min_em
ĺ ´ĺăĺăŽĺĺäťăăŞăšăăćĺŽăăžă@max_it
ă1ă¤ăŽĺăŽăżăćĺŽăăžăăăăŻăăŞăăčăăŚăăăăŽă§ăăďź ăăăžă§ăŻĺä¸ĺăŽäžăŤăăć°ăĽăăăăăŽăŚăźăšăąăźăšăăŤăăźăăăăŠăăăăăăŞăăŁăăŽă§ă質ĺăăžăă
ä¸č¨ăŽăçžĺ¨ăŽć§ćăăŽç§ăŽăăźă¸ă§ăłă§ăŻă.SDăăľăăťăăĺăă䝣ăăăŤget / mgetăč¨čż°ă§ăăžăăăăăăăĺéżăăăă¨ăăĺžĺăăăăžăă ăžăăçžĺ¨ăŽć§ćă§ăŻăăăŽäžă§GForceăĺźăçśăćŠč˝ăăăă¨ă確čŞăăćšćłăăăă¨ćăăžăăăé˘ĺă ă¨ćăăžăă
äťăŽć¸ĺżľăćăĄč˛ ăăĺç´ăăŤé˘ăăčŻăçšă 誏ćăăŚăăăŚăăăă¨ăă ç§ăŻăăă使ç¨ă§ăă/使ç¨ăăă ăăă¨ç˘şäżĄăăŚăăžăă
ç´ ć´ăăăäžă§ăă ă ăăăä¸ăăăăďź
min_em = c("disp", "hp")
min_em_prefix = "min"
mean_em = c("drat", "wt")
mean_em_prefix = "mean"
max_it = "qsec"
max_it_name = "mymax"
by_em = "am"
# goal query
DT[, .(
min.disp = min(disp), min.hp = min(hp),
mean.drat = mean(drat), mean.wt = mean(wt),
mymax = max(qsec)
), by=am ]
ăăăŻéŁăăă§ăďź ăăăăăšăŚăčĄăăă¨ăŻăăăăăç§ăčăăŚăăăăŽă䟸ă°ăăă¨ă§ăă ăăăăăăăăăŁăŚăżăžăăăă ćĺăŤčăăăŽăŻăčŚäťśăĺ¤ăăŽĺ¤ć°ĺă§ăŻăŞă1ă¤ăŽĺŽçžŠăŤä˝çłťĺăăăă¨ă§ăă ăăčŞä˝ădata.tableă¨ăăŚă漽ăăżăŽăăăŤă
> def = data.table( fun = c("min", "mean", "max"),
prefix = c("min", "mean", "max"),
cols=list (c("disp","hp"), c("drat", "wt"), c("qsec") )
> def
fun prefix cols
<char> <char> <list>
1: min min disp,hp
2: mean mean drat,wt
3: max max qsec
揥ăŤăĺŽçžŠăĺąéăăžăă ďźăăŽăšăăăăĺŽčĄăăăăăŽăăčŻăćšćłăăăăŻăă§ăăďź
> expanded = def[, paste0(prefix,".",cols[[1]],"=",fun,"(",cols[[1]],")"), by=1:3]
> expanded
: V1
<int> <char>
1: 1 min.disp=min(disp)
2: 1 min.hp=min(hp)
3: 2 mean.drat=mean(drat)
4: 2 mean.wt=mean(wt)
5: 3 max.qsec=max(qsec)
> J = paste(expanded$V1,collapse=", ")
> J
[1] "min.disp=min(disp), min.hp=min(hp), mean.drat=mean(drat), mean.wt=mean(wt), max.qsec=max(qsec)"
ăăăŚăăă使ç¨ăăă ăă§ăďź
> DT[ " , .(@J), by=<strong i="15">@by_em</strong> " ]
...
Meta-query expanded to: DT[, .(min.disp=min(disp), min.hp=min(hp), mean.drat=mean(drat), mean.wt=mean(wt), max.qsec=max(qsec)), by=am]
...
ăăă§ăŽéŁăăăŽä¸é¨ăŻăčŚäťśăă漽ăăżăćĽé čžă¨ăăŚä˝żç¨ăăăăăăăšăŚăŽćĽ˝ăăżăŤăăăăăăŽĺăă§ăŻăŞăă¨ăăăă¨ă§ăă ăăă§ăŞăăă°ăăăăăăăăŻç°Ąĺă§ăăăă mymax
ĺĺčŚäťśăćşăăăŚăăŞăăă¨ăŻăăăŁăŚăăžăăăćĄĺźľăăŤăăźé˘ć°ăŤçľăżčžźăăă¨ăă§ăăžăă
ĺ
é¨ćéŠĺăä˝ćăăäşşăŽ1äşşă¨ăăŚăăăŽĺ ´ĺăŽćĄĺźľăĄăżăŻă¨ăŞăŻĺšççă§ćéŠĺăăăă¨ç˘şäżĄăăŚăăăăăŽăăăŞăŻă¨ăŞăăăéŠĺăŤĺŚçă§ăăăă¨ăĺŹăăćăăžăă ăăăăăŽlapply
ă .SD
ă setnames()
ăŞăŠăăăšăŚă°ăŤăźăăă¨ăŤĺŽčĄăăăŚăăăăźă¸ă§ăłăćéŠĺăăăă¨ăŤăç§ăŻăžăŁăăćşčśłăăŚăăžăăă çšăŤget
/ mget
ăĺĺ¨ăăĺ ´ĺăăŚăźăśăźăŻ.SD
ăăšăŚăŽĺăĺăĺăăŞăăăăŤă .SDcols
éŠĺăŤć¤č¨ăăŚä˝żç¨ăăĺż
čŚăăăăžăă ćĄĺźľăĄăżăŻă¨ăŞăŤ.SD
ăăŞăĺ ´ĺăăăŽĺéĄăŻč§Łćśăăăžăă
ĺžă§ăăŽčĄăĺçŹă§čŚăă¨ăăăăăäťăŽčŞ°ăăŤăăŁăŚć¸ăăăŚăăžăďź
DT[ " , .(@J), by=<strong i="30">@by_em</strong> " ]
ăŻăăăăăăĄăżăŻă¨ăŞă§ăăăă¨ăçĽăĺż
čŚăăăăžăă ăăăăăăăçĽăŁăŚăăéăă @J
ăć§çŻăăăŚăăă by=
ăăăă°ăŠăăăŁăăŻă§ăăăă¨ăăăăăžăă ćŹčłŞçăŤéŤĺşŚăŞĺçăŻă¨ăŞăŤé˘ăăéăăăăăŻćŞăăă¨ă§ăŻăăăžăăă lapply
ă .SD
ă .SDcols
ă quote
ă bquote
ă as.call
ăŞăŠăŻăăăžăăăĺĺżč
ăŻăé常ăŽdata.tableć§ćăŤĺ°éăăă°ăăăăăăĄăżăŻă¨ăŞăŤé常ăŤç°ĄĺăŤç§ťčĄă§ăăă¨ćăăžăăăăăŻăăŞăăŠăŤćĺĺăŽç˝Žćă§ăăăďźăăăŚç§ăăĄăďźćŻčźçç°ĄĺăŤăăŹăźăšăăăłăăăă°ă§ăăăăă§ăă
ăăăĽăĄăłăă¸ăŽăă1ă¤ăŽăifăăŻăăŞăčŻăă¨ćăăžăă ăăăŻăĄăżăŻă¨ăŞăä˝ă§ăăăă誏ćăăă§ăăăăăăăŚăăăŻç°Ąĺă§ăă 桡䚹ăăă°ăŹăăźăă確çŤăăăŚăă䝣ćżćĄă誏ćăăăăăăŻăăăŤç°Ąĺă§ăă
確ăăŤăç§ă示ăă䝣ćżćĄăŻăĺĺżč ă§ăŻăŞăăçľé¨čąĺŻăŞRăăă°ăŠăăźăŽăăăŽăăŽă§ăă
@ăăŹăăŁăăŻăšăŤĺŻžăă1ă¤ăŽç°č°ăŻăĺä¸ĺ¤ć°ăŽăŚăźăšăąăźăšăăŤăăźăăăăă ăăŤč¨č¨ăăăŚăăăăăŤčŚăăăă¨ă§ăă
ăăăŻä˝ă§ăăŤăăźăăăăăŤč¨č¨ăăăŚăăžăă ĺŽĺ ¨ăŤćčťă
ăťăźĺŽĺ ¨ăŤćčťă§ăă ĺŽĺ ¨ăŤćčťăŞăŽăŻăč¨čŞăŞăă¸ă§ăŻăăŽčŠäžĄč§ŁćăžăăŻćä˝ă§ăă ä¸ă§ä˝żç¨ăăăŻă¨ăŞăŽäžăŻăăăťăŠćç˝ă§ăŻăăăžăăă
DT["<strong i="14">@A</strong> > <strong i="15">@B</strong>, .(<strong i="16">@C</strong> = paste(<strong i="17">@D</strong>, @E), @H), @G"]
ăăŽç´ćĽçżťč¨łăŻćŹĄăŽăăăŤăăăăăĺż čŚăăăăžăă
DT[i = yyy > 0, j = .(NewCol = paste(month, day), list(bar, yyy)), by = foo]
ăăŞăă§ăă ăăďź
DT[i = yyy > 0, j = .(NewCol = paste(month, day), bar, yyy), by = foo]
ăăĄăăăăăŽĺ ´ĺăŻ2çŞçŽăŽăăŽăćłĺŽăăăžăăă @H
ă¨@C
ă1ă¤ăŽăŞăšăăŤăăźă¸ăăăŤăŻăăăăŻă°ăŠăŚăłăă§c
/ unlist
ăă¸ăăŻăĺż
čŚă§ăă ăăăŚăăăăŻĺ¸¸ăŤćăžăăă¨ăŻéăăžăăă
ĺźç¨ăbquoteăas.callăcallăŞăŠăŽé˘ć°ăŽćˇˇäšąăăăăćŹçŞç¨ăŽăăźăŻăłç˝ŽććšćłăäżĄé źăăžăďźJanăăłăĄăłăă§ç¤şăăăăăŤăćŹçŞăŤăŻä¸éŠĺă ă¨ćăăžăďźăăăăă°ă¨äżĺŽăéŁăăă ç§ăŽčŚč§Łă§ăŻăăăźăŻăłç˝ŽććšćłăŻăăĺç´ă§ăăăăăăăŁăŚĺŽéăŤăŻćŹçŞçŽçă§ăăĺ ç˘ă§ăă ăă¨ăă°ăćŹçŞç°ĺ˘ă§ĺŽčĄăăăĺŽéăŽăŻă¨ăŞăŻăă°ăăĄă¤ăŤăŤć¸ăčžźăžăăăăďźevalďźďźăbquoteďźďźăcallďźďźăŞăŠăĺŤăžăăŞăăăă誰ă§ăčŞăżĺăăă¨ăă§ăăžăďźăćŹçŞç°ĺ˘ăŤăă°ă¤ăłăăćšăĺ ç˘ă§ăă ă
ăăăŻćˇˇäšąă§ăŻăŞăă埡ĺă§ćăăăŤč¤éăŞRăĄăżăăă°ăŠăăłă°ćŠč˝ă§ăă ăŻăăRăĄăżăăă°ăŠăăłă°ăĺŽćçăŤä˝żç¨ăăŞăéăăć¸ăăŽăŻéŁăăă§ăă ćĺĺăăă°ăŤč¨é˛ăăăŽă¨ĺăăăăŤăćĺĺăăăăăăă°ăéŁăăăăăžăăăĺźç¨çŹŚă§ĺ˛ăžăăĺźăłĺşăăprint
ăžăăŻdeparse
ăă°ăŤč¨é˛ăăžăă
č¨čŞăŞăă¸ă§ăŻăă使ç¨ăăŚăăăăăĺéĄăŻçşçăăžăăă§ăăă ç§ăŻăă§ăŤä˝ĺš´ăăŽéRbitcoină§
ç§ăŻăĄăżăăă°ăŠăăłă°ăŽăăăŽć°ăăăăăŚăźăśăźăăŹăłăăŞăźăŞćšćłăä˝ăăă¨ăŤĺŽĺ ¨ăŤĺćăăžăăăăăăĺŻč˝ăŞéăćĺ°éăŤćăăăăźăšăŽčŠäžĄč§ŁćăžăăŻč¨čŞăŞăă¸ă§ăŻăăĺŻč˝ăŞéăĺĺŠç¨ăăžăă
č¨čŞRćŠč˝ă§ăŽăłăłăăĽăźăăŁăłă°ă使ç¨ăăăç´ ć´ăăăäžăă
library(data.table)
DT = as.data.table(mtcars)
build.j = function(min_em, min_em_prefix, mean_em, mean_em_prefix, max_it, max_it_name)
as.call(c(
list(as.name(".")),
lapply(setNames(min_em, paste(min_em_prefix, min_em, sep=".")), function(col) call("min", as.name(col))),
lapply(setNames(mean_em, paste(mean_em_prefix, mean_em, sep=".")), function(col) call("mean", as.name(col))),
setNames(list(call("max", as.name(max_it))), max_it_name)
))
qj = build.j(
min_em = c("disp", "hp"),
min_em_prefix = "min",
mean_em = c("drat", "wt"),
mean_em_prefix = "mean",
max_it = "qsec",
max_it_name = "mymax"
)
by_em = "am"
print(qj)
#.(min.disp = min(disp), min.hp = min(hp), mean.drat = mean(drat), mean.wt = mean(wt), mymax = max(qsec))
DT[, eval(qj), by_em] -> ans1
# as single call
qcall = as.call(list(as.name("["), quote(DT), substitute(), qj, as.name(by_em)))
print(qcall)
#DT[, .(min.disp = min(disp), min.hp = min(hp), mean.drat = mean(drat), mean.wt = mean(wt), mymax = max(qsec)), am]
eval(qcall) -> ans2
ăă1ă¤ăŻăăŚăźăśăźćäžăŽĺ
ĽĺăŤĺŻžăăŚeval-parse
ăĺŽčĄăăă¨ăăŽăťăăĽăŞăăŁă§ăă ăăŽĺ ´ĺăč¨čŞă§ăŽč¨çŽăŻăŻăăăŤĺŽĺ
¨ă§ăă
library(data.table)
DT = as.data.table(mtcars)
col = "am"
# eval-parse way
eval(parse(text=paste0("DT[1L,.(",col,")]")))
# am
#1: 1
# language way
eval(as.call(list(as.name("["), quote(DT), quote(1L), call(".", as.name(col)))))
# am
#1: 1
# eval-parse abuse
writeLines("cat('harmful code here\n')", "somescript.R")
col = "{source(\"somescript.R\"); am}"
eval(parse(text=paste0("DT[1L,.(",col,")]")))
#harmful code here
# V1
#1: 1
# try language abuse
eval(as.call(list(as.name("["), quote(DT), quote(1L), call(".", as.name(col)))))
#Error in eval(jsub, SDenv, parent.frame()) :
# object '{source("somescript.R"); am}' not found
ăăăŻădata.tableăŚăźăśăźăŤă¨ăŁăŚăŻăăăťăŠĺéĄă§ăŻăŞăăă˘ăăŞĺ ă§data.tableăĺŠç¨ăăŚăľăźăăăźăăŁăŤUIăćäžăăăéçşč ăŤă¨ăŁăŚăŻĺéĄă§ăă
[ăăăăťăăŚăŹ]ç§ăŻăăŞăăŽăłăĄăłăăŽćŽăăŽĺ¤ăăăăŠăăźăăŚăăžăăă ĺŽéăŽăłăźăäžă確čŞăăĺż čŚăăăăžăăăă¨ăă°ăăĺ¤é¨ăăŽćĺłă100ďź ć確ă§ăŻăŞăăăăăăŽăăźăăŤăăłăźăăŤĺ¤ćă§ăăžăăă
䝼ĺăŽć稿ă硨éăăŚăăăă¤ăăŽäžă¨čŞŹćăĺŤăăžăăă ăăă§ăä¸ćăŞĺ ´ĺăŻăçĽăăăă ăăă
[...]
ďźčŚŞç°ĺ˘ăŽĺĺă¨ăŞăă¸ă§ăŻăăŽăăăžăăăŞăăŤďźĺŽĺ
¨ăŞéć¨ćşčŠäžĄăŤĺăăçśçśçăŞćé ăŻăäžçśă¨ăăŚé常ăŤäžĄĺ¤ăăăă¨ćăăžăă ăăăăć¨ćĽĺăăŚdata.table.R
ă˝ăźăšăčŞăă ä¸ç´ăŚăźăśăźă¨ăăŚăăăăĺŻč˝ăŤăăăăăŽčŞ˛éĄăç解ăăăŤăăăă§ăăăźăćąăăŚăăĺŻč˝ć§ăăăăă¨ăç解ăăŚăăžăă
äťćĽăăăĺŽčŁ ăăĺ ´ĺăç§ăŻăăăăăăăăăă¤ăăŽăąăźăšă§ä˝żç¨ăăă§ăăăă
[1ć]ăă1ă¤ăŻăăŚăźăśăźćäžăŽĺ ĽĺăŤĺŻžăăŚeval-parseăĺŽčĄăăă¨ăăŽăťăăĽăŞăăŁă§ăă
ç§ăŻčŞĺăä˝ćăăăăšăŚăŽĺ
沢ăŽăăă˘ăăŞăąăźăˇă§ăłă§data.tableă使ç¨ăăŚăăžăăăç§ăŻééăăŞăăăăŤă¤ăăŚĺąćŠăŤçăăŚăăăäťăŽäşşăŽč¨ăăă¨ăčăăăă¨ćăŁăŚăăžăă çžĺ¨ăĺ¤ăăŽăŚăźăśăźăeval(parse(text = "..."))
ăăăŞăăŽă§ăăăăŻăăťăăĽăŞăăŁăăŽä˝ä¸ă襨ăăŚăăăŽă§ăăăăăăăă¨ă横ăŤé˛ăă§ăăă ăă§ăăăăă
[ăăăăťăăŚăŤ]ăăăăžăăăăăšăżăźăŤăŞăăžăăă äťăŽă¨ăăj =ă§ä˝żç¨ăăăŚăăč¨ĺˇăŤă¤ăăŚăŽăżă ăăšăŚčŠŚăăŚăżăŚăă ăăă
ăăăŻĺŚĽĺ˝ăŞč¨č¨ä¸ăŽćąşĺŽăăăăăžăăăă ..var
ăĺä¸ăŽĺăĺç
§ăăă¨ăăŤç§ăćĺž
ăăĺä˝ă§ăŻăăăžăăă
DT = data.table(x=1:3, y=2:4)
var = "x"
DT[, x] ## Returns a vector
DT[, ..var] ## Returns a one column data.table with column x
DT = data.table(x=1:3, y=2:4)
var = "x"
DT[, paste(..var)] # ..var evaluates as column x
# x
# 1: 1
# 2: 2
# 3: 3
DT[, paste(..var, x)] # ..var evaluates as string "x"
# [1] "x 1" "x 2" "x 3"
DT[, paste("blah",..var)] # ..var is concatenated by paste
# Error in `[.data.table`(DT, , paste("blah", ..var)) :
# column(s) not found: blah x
x = "foo"
var = "x"
dt[, paste("blah",get(..var))] # get(..var) "redirected" to global variable x
# Error in `[.data.table`(dt, , paste("blah", get(..var))) :
# column(s) not found: blah foo
dt[, .(paste("blah",..var))] # When wrapped in .() behavior is as expected
# V1
# 1: blah x
dt[, .(paste("blah",get(..var)))] # When wrapped in .() behavior with get() is also as expected
# V1
# 1: blah 1
# 2: blah 2
# 3: blah 3
get()
ă使ç¨ăăĺż
čŚăăăăžă[Matt Dowle]ăăŠăłăŻ-ăăăăžăăăgďźďźăŤă¤ăăŚăŽăăŞăăŽčăăăăăăžăăă ăă ăăgďźďźă罎ćăăĺ ´ĺăŻăăăźăŻăłç˝Žćă使ç¨ăăăă¨ăă§ăăžăă ăăŽăăăŞăłăźăăŽčŞč ăŻăgďźďźă¨ăŻä˝ăăăăăŚăăăä˝ăăăăăçĽăĺż čŚăăăăžăă ăĄăżăŻă¨ăŞă˘ăźăăăăć確ăŤç¤şăăŤăŻăăŤăăŻă˘ăłăăăŁăźăŤăăăĺçăŤĺăćżăăĺż čŚăăăă¨ćăăžăă
ĺŽç§ăŞä¸çă§ăŻăăăŽĺ ´ĺăŽć°ăăăăŹăăŁăăŻăšăŤăăăăźăŻăłăŽç˝Žćăăç§ăŤă¨ăŁăŚçćłçă¨ćăăăĺä¸ăŽćĺĺăŤăăšăŚăĺ ĽăăăŤĺŽčĄă§ăăĺ ´ĺă ćéŠĺăŽčŞ˛éĄăŤă¤ăăŚĺĺăŤç解ăăŚăăŞăăŽă§ăăăăăŠăăťăŠçžĺŽçă§ăăăăŠăăăç解ă§ăăžăăă
ăăă§ă風ĺăŽć°´ă§čľ¤ăĄăăăć¨ăŚăăăŞăăŽă§ăăă ..
ăçľăăăŤăŞăăŞăăŚăăăžă ä˝ăăăŽäžĄĺ¤ăăăăăăăăžăă-ăăšăŚdata.tableăŽNSEăŽč§Łćąşçă§ăă
çžçśă§ăŻăăšăżăăŻăŞăźăăźăăăźăŽčłŞĺăŤĺŻžăăĺçăćäžăăžă
ăžăăăăŽäžăŻç§ăćĺž ăăă¨ăăăŤćŠč˝ăăžăă
DT = data.table(foo = LETTERS[1:5],
bar = seq_len(5),
baz = seq_len(5)/10,
zero = 0L)
x = "foo"
y = "bar"
z = "baz"
string1 = "blah"
num1 = 10
DT[, .(Paste = paste(..string1, get(..x), get(..y),sep = "-"),
Mult = get(..y)*..num1,
Add = get(..y) + get(..z),
foo_literal = foo,
foo_ref = get(..x))]
@msummersgillĺĺĽăŽăˇăłăăŤăŽĺŠçšăŽ1ă¤ăŻăĺă確ĺŽăŤĺĺžă§ăăăă¨ă§ăă
library(data.table)
DT = data.table(foo = LETTERS[1:5],
bar = seq_len(5),
baz = seq_len(5)/10,
zero = 0L)
# current behavior
x = "foo"
DT[, {foo = "yeehaw"; get(..x)}]
# [1] "yeehaw"
# whereas i guess the plan is
DT[', {foo = "yeehaw"; @x}']
# [1] "A" "B" "C" "D" "E"
ĺć§ăŤăăťăăĽăŞăăŁăŤé˘ăăŚăŻă@ selectĺăŽăżăĺŽĺ ¨ă§ăăăăăŤćăăăăŽă§...
DT1 = data.table(a = 1, b = 2)
f1 = function(x, d = DT) d[", code_vulnerable_if_x_is_bad(@x)"]
# should error for any input that isn't a column selection
# and even if the column name contains dangerous code
DT2 = data.table(`dangerous code here` = 1)
f2 = function(x, d = DT2) DT[", f(@x)"]
# should select the named column, not evaluate its name
ăžăăéçşč
ăŻăăŚăźăśăźăäťťćăŽăłăźăăćĺĺă¨ăăŚćżĺ
Ľă§ăăf (char_expr, d = DT) DT[char_expr]
ăăăŞé˘ć°ăč¨čż°ăăŞăă§ăă ăăă ă¨ăŤăăăăăăŻććĄăŽç§ăŽç解ă§ăă
揥ăŤăĺŽçžŠăĺąéăăžăă ďźăăŽăšăăăăĺŽčĄăăăăăŽăăčŻăćšćłăăăăŻăă§ăăďź
ăăă§ç°č°ăĺąăăăă¨ăŻăăŚăăžăăăăć確ăŤăăăăăŤăăăčŻăćšćłăŻcall
ă¨as.call
ă§ă...ăăăăăăŽćĄĺźľăŻă¨ăłăăŚăźăśăźă§ăŻăŞădata.tableăŤăăŁăŚčĄăăăžăăăďź ăăăăŁăŚăăăăăŽč¨čŞăăă°ăŠăăłă°ćŠč˝ăŤç˛žéăăŚăăĺż
čŚăăăăăă§ăŻăăăžăăă JanăŽăłăźăăäžăŤĺŻžăăŚăăžăăŤăçšćł¨ăŤčŚăăĺ ´ĺăŻă揥ăŽăăăŤăŞăăžă...
library(data.table)
DT = data.table(mtcars)
# note: changing "prefix" to name to also cover mymax .. not a big extension
def = data.table(fun = c("min", "mean", "max"),
name = c("min", "mean", "mymax"),
cols=list (c("disp","hp"), c("drat", "wt"), c("qsec") ))
def[, ncols := lengths(cols)]
longdef = def[, c(.SD[rep(.I, ncols)], .(col = unlist(cols))), .SDcols=!"cols"]
longdef[, out_name := sprintf("%s.%s", fun, col)][ncols == 1, out_name := name]
expr = with(longdef,
as.call(c(as.name("list"),
setNames(Map(call, fun, lapply(col, as.name)), out_name)
))
)
DT[, eval(expr), by=am]
@mattdowleă§ăŻă call
/ as.call
ă使ç¨ăăŚăăăŽăăăŞćĄĺźľăčĄăăă¨ăŤç°č°ăăăăžăăďź ăăăăăŞăăăăăŻă¨ăłăăŚăźăśăźă¤ăłăżăźăă§ăźăšăăŠăŽăăăŤčŚăăăă¨ăŻĺĽăŽčłŞĺăŽăăăŤćăăžăďź@ă¨ćĺĺĺ
ĽĺăŽčłŞĺďźă ăăăŚăJanăčăăŚăăćšćłďźďź852ďźă§[.data.table
ăăă˘ă¸ăĽăźăŤĺăăăă¨ăŻăăăźăăŽăăăŤćăăžăăďź
ç§ăŻăăŽăăă¸ă§ăŻăăŤč˛˘çŽăăăă¨ăăăăžăăăŽă§ăăăăŻĺŽäžĄăŞčŠąă ăăç§ăćłĺďź852ăŻç§ăŽăăăŞć˝ĺ¨çăŞč˛˘çŽč ă¸ăŽéĺŁăä¸ăăă ăăă¨ă ăăăăç§ăŻăăŽĺéĄăăăŞăăăăă§č¨ăŁăŚăăăă¨ă誤解ăăŚăăăăăăăžăăă
ăăă䝼ĺăŤĺŻžĺŚăăăŚăăăăŠăăăŻăăăăžăăăăć°ăă..ăăŹăăŁăăŻăšăäťŁĺ ĽćźçŽĺďź=ă§ăćŠč˝ăăăă¨ăăŠăŽăăăŤç˘şčŞăăžăăďź
揥ăŽäžăčăăŚăżăžăăăă
dt <- data.table(x=rnorm(10), y=runif(10));
dt[, x := x + 1]
ăăăŻĺŽĺ
¨ăŤĺăĺ
Ľăăăăžăă ăăă°ăŠă ă§xăčŚă¤ăăĺż
čŚăăăĺ ´ĺăŻăĺăŤăăăčĄăăžă
a <- "x";
dt[, eval(as.name(a)) := eval(as.name(a)) + 1]
ă
data.tableăăăąăźă¸ăv1.10.4ăŤć´ć°ăăăžă§ăŻăĺŽĺ
¨ăŤćŁĺ¸¸ăŤćŠč˝ăăŚăăžăăă
äťăŻă§ăăžăădt[, z:=..a]
ăžădt[, ..a := ..a + 1]
ăăăăŻ
dt[, eval(as.name(a)) := eval(as.name(a)) + 1]
ăăă ćĽé čžă使ç¨ăăŚäťŁĺ
Ľćä˝ăĺŽčĄă§ăăŞăĺ ´ĺăćĽé čžăŽăă¤ăłăăŻä˝ă§ăăďź ĺ¤ăevalďźas.nameďźVARďźďźăĺŁăăĺĺ ăçĽăŁăŚăăäşşăŻăăžăăďź ăăăă¨ăă
@jjyyyinăłăĄăłăăć°ăăĺˇăŤăłăăźăăžăăăăăă§ăăŁăšăŤăăˇă§ăłăăăŠăăźă˘ăăăăŚăă ăăă https://github.com/Rdatatable/data.table/issues/2816
ăăŁăšăŤăăˇă§ăłĺ
¨ä˝ăĺç´ăŞĺăŽé¸ćďź ..
ăăŹăăŁăăŻăšďźăă大ăăé¸čąăăăăăăżă¤ăăŤăĺ¤ć´ăăžăăă
ĺĽăŽäťŁćżć掾ăŻă substitute
ă¨ăăŽenv
ĺźć°ăŤéĄäźźăăă¤ăłăżăźăă§ăźăšăćäžăăăă¨ă§ăă
DT[, .(out_col = fun(in_col)), by=by_col,
env = .(out_col="mpg_max", fun="max", in_col="mpg", by_col="cyl")]
env
ăŞăšăăŽăăšăŚăŽčŚç´ ăŻăˇăłăăŤăŤĺ¤ćăăă i
ă j
ă by
ă..ăŤç˝Žăćăăăăžăă
ăăźăšRă使ç¨ăăĺŽäžăLHSĺăé¤ăăŚăăăăŻćł¨ćăĺż čŚă§ăă
x = list()
class(x) = "cl"
"[.cl" = function(x, i, j, env) {
if (!missing(env) && length(env)) {
stopifnot(is.list(env), sapply(env, is.character))
env = lapply(env, as.symbol)
isub = eval(substitute(substitute(i, env)))
jsub = eval(substitute(substitute(j, env)))
} else {
isub = substitute(i)
jsub = substitute(j)
}
list(isub=isub, jsub=jsub)
}
x[var1==5L & var2%in%c("a","b"),
.(fvar1=fun(var1, na.rm=TRUE), charhead=head(var2, 1L))]
#$isub
#var1 == 5L & var2 %in% c("a", "b")
#$jsub
#.(fvar1 = fun(var1, na.rm = TRUE), charhead = head(var2, 1L))
x[var1==5L & var2%in%c("a","b"),
.(fvar1=fun(var1, na.rm=TRUE), charhead=head(var2, 1L)),
env = list(var1="myIntCol", var2="myCharCol", fun="sum")]
#$isub
#myIntCol == 5L & myCharCol %in% c("a", "b")
#$jsub
#.(fvar1 = sum(myIntCol, na.rm = TRUE), charhead = head(myCharCol, 1L))
LHSĺăŽĺŚçćšćłăćŻć´ăăŚăăă@ggrothendieckăŤćčŹăăžăă
x = list()
class(x) = "cl"
"[.cl" = function(x, i, j, env) {
if (!missing(env) && length(env)) {
stopifnot(is.list(env), sapply(env, is.character), sapply(env, nzchar))
env = lapply(env, as.symbol)
isub = if (!missing(i)) eval(substitute(substitute(i, env)))
jsub = if (!missing(j)) eval(substitute(substitute(j, env)))
# substitute names?
if (any(w <- names(jsub) %in% names(env))) {
names(jsub)[w] = unlist(lapply(env[names(jsub)[w]], as.character))
}
} else {
isub = substitute(i)
jsub = substitute(j)
}
list(isub=isub, jsub=jsub)
}
x[, .(fvar1=list(fvar2 = val1)),
env = list(fvar1="outer", fvar2="inner", val1="val_column")]
#$isub
#NULL
#$jsub
#.(outer = list(fvar2 = val_column))
ćŽĺżľăŞăăăLHSăŽăăšăăăă罎ćăć˘ăăŤăŻăĺźăĺ帰çăŤăăŠăăźăšăăĺż
čŚăăăăžăă RHSăŻăă§ăŤsubstitute
ăŤăăŁăŚéŠĺăŤĺŚçăăăŚăăžăă
ăăšăăăăĺźăłĺşăă§ĺĺă罎ăćăăăăăŽĺ帰çăăŠăăźăšăŻăPRďź4304ă§ĺŻžĺŚăăăŚăăžăă substitute2
é˘ć°ăŻăĺ¤ć°/é˘ć°ĺďźRăŽsubstitute
ăŤăăŁăŚĺŚçăăăĺźć°ĺăĺźăłĺşăďźć°ăăĺ
é¨substitute_call_arg_namesR
é˘ć°ăŤăăŁăŚĺŚçăăăďźďźăŽä¸ĄćšăŽĺ¤ă罎ăćăăăăăŤĺ°ĺ
Ľăăăžăăă
ćăĺčăŤăŞăăłăĄăłă
čŻăďź ç§ă弽ăă§ăă ăžăăĺŽčŁ ăăă¨ă揥ăŽăăăŞĺéĄăŤĺŻžĺŚăăžăă
ăăŽĺžă揥ăŽăăăŤĺŽčĄă§ăăžăă