Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

implementation of dot function `.()` in data.table package [duplicate]

from ?data.table::data.table :

The expression '.()' is a shorthand alias to list(); they both mean the same

However this function is nowhere to be found :

data.table:::.

Error in get(name, envir = asNamespace(pkg), inherits = FALSE) :
object '.' not found

So I suppose the input is parsed somehow, how is it done ? I'd like to use the same feature in my own package.

The following works not too bad :

test  <- function(x) {
  eval(substitute(
    eval.parent(substitute(x, list(.=list)))
    ))
}

foo <- "bar"
test(.(foo))
# [[1]]
# [1] "bar"
identical(test(.(foo)), list(foo))
# [1] TRUE

However there will be some dot variables used inside this dot function, and this fails :

. <- "baz"
test(.(foo,.))
# [[1]]
# [1] "bar"
# 
# [[2]]
# function (...)  .Primitive("list")

Expected :

# [[1]]
# [1] "bar"
# 
# [[2]]
# [1] "baz"
like image 641
Moody_Mudskipper Avatar asked Jun 03 '26 16:06

Moody_Mudskipper


1 Answers

The data.table package accomplishes it with this bit of code

replace_dot_alias <- function(e) {
  # we don't just simply alias .=list because i) list is a primitive (faster to iterate) and ii) we test for use
  # of "list" in several places so it saves having to remember to write "." || "list" in those places
  if (is.call(e)) {
    # . alias also used within bquote, #1912
    if (e[[1L]] == 'bquote') return(e)
    if (e[[1L]] == ".") e[[1L]] = quote(list)
    for (i in seq_along(e)[-1L]) if (!is.null(e[[i]])) e[[i]] = replace_dot_alias(e[[i]])
  }
  e
}

found in R/data.table.R (currently at line 173). That's why you don't find data.table:::. anywhere, and how they accomplish the parsing you mention in your post.

Then in [.data.table" <- function (x, i, j,... they can do this sort of thing

if (!missing(j)) {
    jsub = replace_dot_alias(substitute(j))
    root = if (is.call(jsub)) as.character(jsub[[1L]])[1L] else ""

....

like image 116
duckmayr Avatar answered Jun 06 '26 06:06

duckmayr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!