Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: .() mis-interpreted when being used as plotmath #1912

Closed
MichaelChirico opened this issue Nov 12, 2016 · 5 comments
Closed

Bug: .() mis-interpreted when being used as plotmath #1912

MichaelChirico opened this issue Nov 12, 2016 · 5 comments
Milestone

Comments

@MichaelChirico
Copy link
Member

@MichaelChirico MichaelChirico commented Nov 12, 2016

I just found out that sometimes .() is needed to create dynamically-labeled plots in base R:

png("~/Desktop/dterror.png")
par(mfrow = c(1, 2))
DT[ , {
  plot(1:10)
  text(2, 9, bquote(R^2 == .(summary(lm(y ~ x))$r.squared)))}]

plot(1:10)
text(2, 9, bquote(R^2 == .(summary(lm(y ~ x, data = DT))$r.squared)))
dev.off()

dterror

When used outside of [.data.table, the text is converted (as expected) to the evaluated value of the regression. But [.data.table (I imagine) is detecting this as an alias for list and substituting, leading to the unexpected result on the left.

Workaround for now is to use with(DT, {...}) instead of calling [.data.table but obviously this won't work in situations requiring other arguments of [.data.table.

@jangorecki

This comment has been minimized.

Copy link
Member

@jangorecki jangorecki commented Nov 13, 2016

You can try bquote(DT[...]).

@MichaelChirico

This comment has been minimized.

Copy link
Member Author

@MichaelChirico MichaelChirico commented Nov 13, 2016

that would make the plot expression much more verbose... the bquote part is
two of maybe 20 lines within j to create the full plot.

if there's no fast way to to put a check on the dot replacement for its
being inside bquote, than so be it I guess... seeing as how this is the
first time I've come across it in ~3 yrs of using data.table, wouldn't be
the that big a deal in the grand scheme of things.

could add a replace_dot argument/option to be shut off in such rare cases?

On Nov 13, 2016 8:33 AM, "Jan Gorecki" notifications@github.com wrote:

You can try bquote(DT[...]).


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
#1912 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AHQQdR4wXJhYq96dR-fGNEi45nBvTynaks5q9xGqgaJpZM4KwjmM
.

@jangorecki

This comment has been minimized.

Copy link
Member

@jangorecki jangorecki commented Nov 13, 2016

This should be a matter of changing "." value in this line. You could eventually put getOption("datatable.listalias", ".") and control that dynamically, but I don't think use case you mention is enough for putting such "feature." I would go with ?substitute (@MichaelChirico) instead of bquote.

@MichaelChirico

This comment has been minimized.

Copy link
Member Author

@MichaelChirico MichaelChirico commented Nov 13, 2016

Hmm, I tried other ways of getting around bquote but never got anything to work. Specifically?

@ecoRoland

This comment has been minimized.

Copy link

@ecoRoland ecoRoland commented Jan 24, 2017

I second this since I occasionally plot in j and even have a package that does so. Just add a check for bquote:

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)) {
    if (e[[1L]] == "bquote") return(e) #check for bquote
    if (e[[1L]] == ".") e[[1L]] = quote(list)
    
    for (i in seq_along(e)[-1]) if ((!is.null(e[[i]])) && 
                                               (e[[i]] != "bquote")) #check for nested bquote
       e[[i]] = replace_dot_alias(e[[i]])
  }
  e
}

replace_dot_alias(quote(.(k)))
#list(k)
replace_dot_alias(quote(bquote(.(k))))
#bquote(.(k))
replace_dot_alias(quote(c(.(k), .(l))))
#c(list(k), list(l))
replace_dot_alias(quote(c(.(k), .(bquote(m == .(l))))))
#c(list(k), list(bquote(m == .(l))))

Currently, I have to use parse:

DT[, {
  i <- 42
  parse(text = sprintf("mu == %i", i))
}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.