In-line comments below. Bill Dunlap Spotfire, TIBCO Software wdunlap tibco.com
> -----Original Message----- > From: r-help-boun...@r-project.org [mailto:r-help-boun...@r-project.org] On > Behalf > Of Rolf Turner > Sent: Friday, October 05, 2012 5:02 PM > To: Uwe Ligges > Cc: r-help@r-project.org > Subject: Re: [R] Format of numbers in plotmath expressions. > > > > Thanks Uwe. I think your recipe is substantially sexier than mine. > > However I will, I believe, ***NEVER*** understand how to put together > plotmath constructs. They seem to require some subset of: > > * expression() > * bquote() > * substitute() > * parse() Note that using parse was one source of your original problem. You did the equivalent of parse(text=paste("theta", "1.0000", sep="==")) which gives the same result as parse(text=paste("theta", "1", sep="==")) because "x==1.0000" and "x==1" should be parsed to be the same expression. If you wanted the string "1.0000" to come out of parse then you would have to quote it, as in legend("topleft",pch=1:5,legend=parse(text=paste0("theta == \"",TH,"\""))) instead of your original legend("topleft",pch=1:5,legend=parse(text=paste0("theta == ", TH))) This works because plotmath does not render the quotes in strings. I would recommend taking parse(), paste(), substitute(), and even expression() off your list of things to try when using plotmath. For single chunks of plotmath text, isn't bquote() sufficient? For multiple chunks (e.g., the strings given to legend or axis) I think you can restrict yourself to the idiom as.expression(lapply(data, function(d)bquote(...))) mapply would be fine here also, but I would avoid sapply, as its simplification algorithm can surprise you. expression() is good when you have a fixed (parameterless) expression you want to display, but bquote is just as good, so don't bother thinking about using expression() in plotmath. Here is an example of mapply used to make axis tick labels of the form num * pi / den, leaving out unneeded 1's, and related legend labels: curve(sin, from=0, to=6.5, axes=FALSE) num <- 0:8 ; den <- 4 # want labels num * pi / den, simplified when possible labs <- as.expression(mapply(num, den, SIMPLIFY=FALSE, FUN=function(n, d) { gcd <- function(a,b) ifelse (b==0, a, gcd(b, a %% b)) div <- gcd(n, d) if (div > 1) { n <- n / div ; d <- d / div } if (n==0) { bquote(0) } else if (d==1) { if (n==1) { bquote(pi) } else { bquote(.(n)*pi) } } else { if (n==1) { bquote(pi/.(d)) } else { bquote(.(n)*pi/.(d)) } } } )) axis(side=1, at=num*pi/den, lab=labs) # Now put theta= on the front of each label for the legend legend("bottomleft", as.expression(lapply(labs, function(lab)bquote(theta==.(lab))))) I am not an expert on plotmath, but my feeling from watching people use it is that they tend to lose track of the boundary between standard R functions and the functions by the same name used by plotmath for different purposes By sticking to using bquote() for creating single plotmath exressions and as.expression(lapply(..., function(x)bquote(.(x)))) for collections of plotmath expressions, you can concentrate on the learning the plotmath language itself. Are there plotmath expressions that cannot be made with bquote instead of parse(text=paste(...))? Perhaps not, but some with a variable number of components may be more easily done with parse. > * paste() > * as.expression() > * .(...) > > (and quite possibly other things that I have forgotten) in a bewildering > variety of combinations with no perceptible rationale as what combination > is required in what circumstances. > > It makes quantum mechanics look simple by comparison. > > cheers, > > Rolf > > On 06/10/12 06:58, Uwe Ligges wrote: > > > > > > On 05.10.2012 09:30, Rolf Turner wrote: > >> > >> I want to do something like: > >> > >> TH <- sprintf("%1.1f",c(0.3,0.5,0.7,0.9,1)) > >> plot(1:10) > >> legend("bottomright",pch=1:5,legend=parse(text=paste("theta ==",TH))) > >> > >> Notice that the final "1" comes out in the legend as just plain "1" > >> and NOT > >> as "1.0" although TH is > >> > >> [1] "0.3" "0.5" "0.7" "0.9" "1.0" > >> > >> I can get plotmath to preserve "1.0" as "1.0" and NOT convert it to "1" > >> if I use substitute, as in > >> > >> text(2,5,labels=substitute(list(theta == a),list(a=TH[5]))) > >> > >> but substitute doesn't work appropriately with vectors. > >> > >> Can anyone tell me how to get a "1.0" rather than "1" in the legend? > >> > >> Ta. > >> > >> cheers, > >> > >> Rolf Turner > >> > >> P.S. Just figured out a way using sapply(): > >> > >> leg <- sapply(TH,function(x){substitute(list(theta == a),list(a=x))}) > >> plot(1:10) > >> legend("bottomright",pch=1:5,legend=parse(text=leg)) > >> > >> Note that the use of "parse" (pace Thomas Lumley! :-) ) is required --- > >> "legend=leg" does NOT work. > >> > >> Getting here required an enormous amount of trial and error. And it > >> seems > >> pretty kludgy. > >> > >> Is there a sexier way? > > > > > > Not sure what is sexier here. I'd stay with > > > > leg <- lapply(TH, function(x) bquote(list(theta == .(x)))) > > plot(1:10) > > legend("bottomright", pch=1:5, legend=as.expression(leg)) > > > > > > Best, > > Uwe Ligges > > > > > > > >> > >> R. T. > >> > >> ______________________________________________ > >> R-help@r-project.org mailing list > >> https://stat.ethz.ch/mailman/listinfo/r-help > >> PLEASE do read the posting guide > >> http://www.R-project.org/posting-guide.html > >> and provide commented, minimal, self-contained, reproducible code. > > > > ______________________________________________ > R-help@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.