[R] plotmath and logical operators?

William Dunlap wdun|@p @end|ng |rom t|bco@com
Tue Aug 21 04:12:43 CEST 2018

A generalization of Bert's suggestion is

plotSubset <- function (data, subset, qsubset = substitute(subset))
{
sdata <- data[eval(qsubset, data), ]
with(sdata, plot(x, y, main = subsetToPlotmath(expr = qsubset)))
}

subsetToPlotmath <- function(expr) {
# Argument 'expr': an expression used as subset argument to subset()
# Return: an expression used by plotmath that is more readable to
non-programming people
if (is.call(expr)) {
for(i in seq_along(expr)) {
expr[[i]] <- subsetToPlotmath(expr[[i]])
}
if (is.name(funcName <- expr[[1]]) && !is.null(func <-
env.subsetToPlotmath[[as.character(funcName)]])) {
expr <- do.call(func, as.list(expr[-1]))
}
}
expr
}
env.subsetToPlotmath <- new.env()
env.subsetToPlotmath[["&"]] <- function(x, y) substitute(x ~ italic(and) ~
y)
env.subsetToPlotmath[["|"]] <- function(x, y) substitute((x) ~ italic(or) ~
(y)) # internal parens not always needed
env.subsetToPlotmath[["log10"]] <- function(x)
substitute(italic(log)[10](x))
env.subsetToPlotmath[["exp"]] <- function(x) substitute(italic(e)^x)

You can add more conversions to the environment env.subsetToPlotmath.

Try it with

> df <- data.frame(x=1:5, y=1:5)
> plotSubset(df, x<1.5 | y>3.5) # see title "(x < 1.5) or (y > 3.5)" and
pts at x=1,4,5.

It doesn't get right the parentheses needed to enforce the order of
evaluation:
it always puts parentheses around the arguments to | and never puts them
around the arguments to &.

Bill Dunlap
TIBCO Software
wdunlap tibco.com

On Mon, Aug 20, 2018 at 4:14 PM, MacQueen, Don via R-help <
r-help using r-project.org> wrote:

> Thanks Bert!
>
> It certainly works for the example (and shows a much deeper understanding
> of eval, substitute, etc. than I have). But it doesn't appear to generalize
> very well in the way I need (which of course I didn't think of mentioning
> until after I sent the email -- sorry).
>
> Suppose subs is any expression that would be valid for the subset argument
> of base::subset, for a given data frame. Then I can extract that subset of
> the data frame by using
>    mydf[  with(mydf, eval(subs)) ,  ]
> (or similar).
>
> Then, having plotted some aspect of that subset, I want to annotate the
> plot with the subset specifications.
>
> I've used this approach to  set up a system that helps me to interactively
> review various subsets of a large set of data. I save the final selected
> subsetting expressions in some sort of data structure, for later use in
> preparing a report using rmarkdown.
>
> I was hoping to use plotmath to improve the appearance of the annotations
> -- but I now think it's not worth this kind of effort. I think I'm going to
> settle for mtext( as.character(subs) ).
>
> -Don
>
> --
> Don MacQueen
> Lawrence Livermore National Laboratory
> 7000 East Ave., L-627
> Livermore, CA 94550
> 925-423-1062
> Lab cell 925-724-7509
>
>
>
> From: Bert Gunter <bgunter.4567 using gmail.com>
> Date: Monday, August 20, 2018 at 3:38 PM
> To: "MacQueen, Don" <macqueen1 using llnl.gov>
> Cc: array R-help <r-help using r-project.org>
> Subject: Re: [R] plotmath and logical operators?
>
> This is clumsy and probably subject to considerable improvement, but does
> it work for you:
>
> left <- quote(x >= 3)
> right <- quote(y <= 3) ## these can be anything
>
> ## the plot:
> plot(1)
> eval(substitute(mtext(expression(paste(left, " & ",right))), list(left =
> left, right = right)))
>
> ## Expression evaluation
> eval(substitute(with(df,left & right), list(left = left, right = right)))
> Cheers,
> Bert
>
>
> Bert Gunter
>
> "The trouble with having an open mind is that people keep coming along and
> sticking things into it."
> -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )
>
>
> On Mon, Aug 20, 2018 at 2:00 PM MacQueen, Don via R-help <
> r-help using r-project.org<mailto:r-help using r-project.org>> wrote:
> I would like to use plotmath to annotate a plot with an expression that
> includes a logical operator.
>
> ## works well
> tmp <- expression(x >= 3)
> plot(1)
> mtext(tmp)
>
> ## not so well
> tmp <- expression(x >= 3 &  y <= 3)
> plot(1)
> mtext(tmp)
>
> Although the text that's displayed makes sense, it won't be obvious to my
> non-mathematical audience.
>
> I'd appreciate suggestions.
>
>
> I've found a work-around that gets the annotation to look right
>   tmpw <- expression(paste( x >= 3, " & ", y <= 3) )
>   plot(1)
>   mtext(tmpw)
>
>
> But it breaks my original purpose, illustrated by this example:
>
> df <- data.frame(x=1:5, y=1:5)
> tmp <- expression(x >= 3 & y <= 3)
> tmpw <- expression(paste( x >= 3, " & ", y <= 3) )
> with(df, eval(tmp))
> [1] FALSE FALSE  TRUE FALSE FALSE
> with(df, eval(tmpw))
> [1] "FALSE  &  TRUE" "FALSE  &  TRUE" "TRUE  &  TRUE"  "TRUE  &  FALSE"
> "TRUE  &  FALSE"
>
> Thanks
> -Don
>
> --
> Don MacQueen
> Lawrence Livermore National Laboratory
> 7000 East Ave., L-627
> Livermore, CA 94550
> 925-423-1062
> Lab cell 925-724-7509
>
>
>
> ______________________________________________
> R-help using r-project.org<mailto:R-help using r-project.org> mailing list -- To
> UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>
>         [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help