[R] Pasting R code lines into labels

Marc Schwartz m@rc_@chw@rtz @end|ng |rom me@com
Fri Jun 7 16:20:32 CEST 2019


Hi Martin,

See inline below...

> On Jun 7, 2019, at 9:25 AM, Martin Maechler <maechler using stat.math.ethz.ch> wrote:
> 
>>>>>> Marc Schwartz via R-help 
>>>>>>    on Fri, 7 Jun 2019 09:07:21 -0400 writes:
> 
>> Hi, Ok, some additional tweaks.
> 
>> Relative to Bert's pointing out the aesthetic issues,
>> certainly, those are attributes that can be adjusted as
>> Nick may require. I was focused more on the primary
>> issue. Using "..." is an easy way to pass additional
>> parameters to plot.default() as Bert indicated.
> 
>> To Duncan's point, here is a modification of my original
>> function to allow for the passing of an expression, rather
>> than pre-creating a function and passing that:
> 
>> plotFx <- function(x, expr, ...) {
>>  expr <- substitute(expr)
>> y <- eval(expr)
>>  plot(x, y, main = paste0("Plot of y = ", deparse(expr)), ...)
>> }
> 
>> plotFx(1:10, x^2)
>> plotFx(1:10, cos(x))
>> plotFx(1:10, exp(x) + 1)
> 
> well yes....
> 
> Ross/Robert/??  had invented  the  curve()   function to do
> something like that even before R got a version number !!
> and we (it may have been me) had added a
> 
> plot.function()   method for plot()  which behaved very
> similarly, also long before R version 1.0.x
> 
> Are you sure you don't want to use one of
> 
>    plot(<function>, ...)
> or
>    curve(..)
> 
> instead of what you are doing now?


Very possibly, and thank you for rightly pointing those out Martin!

I think that, at least for me on initial reading, the focus was on the need for a plot title that combined the paste()d character vector of "Plot of y = " with the expression on 'x' itself, as perhaps opposed to the y axis labeling as generated by default in those two functions. My initial attempt with plotmath below, was incorrectly focused on the need for a TeX-like formatting of the title.

I guess, it will depend upon Nick's specific use case and labeling requirements and if the default approach in these two functions in creating the y axis labels, as opposed to a plot title, are satisfactory.

Also, unless I missing a nuance in the functions, with plot.function() calling curve() internally, they appear to allow the specification of the min/max range of x values to use and then plotting an equally spaced number of x values within that range (e.g. x <- seq(from, to, length.out = n)), rather than explicitly defining/passing a vector of x values to use. That may be something that Nick wishes to do.


> Look at the result of
> 
>  example(plot.function)
> 
> and
> 
>  example(curve)
> 
> to get a bit of a show-off of these ..


Indeed. Be aware that both functions are on the same help page, thus running the examples above will run the same code.


> 
>> There are likely additional tweaks that could be made, as Nick may require.
> 
>> Regards,
>> Marc
> 
> ... tweaks which may already be available in curve() / plot.function().
> At the time, I had invested many many man hours to tweak them to
> become as versatile as seemed feasible ...
> 
> Martin Maechler
> ETH Zurich and R Core


Indeed, and thank you again Martin for rightly pointing these out.

Regards,

Marc

> 
> 
> 
>>> On Jun 6, 2019, at 5:53 PM, Duncan Murdoch <murdoch.duncan using gmail.com> wrote:
>>> 
>>> These look like very fragile suggestions.  Allow x^2 to be an argument (named expr, for example) to plotFx, don't force a user to write a function in a very particular way.  Then use deparse(substitute(expr)) in the title.
>>> 
>>> Duncan Murdoch
>>> 
>>> On 06/06/2019 4:33 p.m., Bert Gunter wrote:
>>>> Well, if you want to do it this way, note that as written, the y axis
>>>> default label isn't "nice," and you should anyway allow for additional
>>>> graphical arguments (either way). Also, slightly better I think is to use
>>>> the built-in access function, body():
>>>> plotFx <- function(x, fun, ...) {
>>>> plot(x, fun(x), main = paste0("Plot of y = ", deparse(body(fun))), ...)
>>>> }
>>>> x <- 1:10
>>>> f <- function(x) x^2
>>>> plotFx(x, f, col = "red", ylab = "y")
>>>> 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 Thu, Jun 6, 2019 at 12:19 PM Marc Schwartz <marc_schwartz using me.com> wrote:
>>>>> Hi,
>>>>> 
>>>>> Sorry for the misfire on the first attempt.
>>>>> 
>>>>> After seeing the clarifications, I thought about a possible way to do
>>>>> this, perhaps a little more simply, while encapsulating the plotting in a
>>>>> function:
>>>>> 
>>>>> plotFx <- function(x, fun) {
>>>>> plot(x, fun(x), main = paste0("Plot of y = ", deparse(fun)[2]))
>>>>> }
>>>>> 
>>>>> So let's say that you have:
>>>>> 
>>>>> x <- 1:10
>>>>> 
>>>>> f <- function(x) x^2
>>>>> plotFx(x, f)
>>>>> 
>>>>> f <- function(x) cos(x)
>>>>> plotFx(x, f)
>>>>> 
>>>>> f <- function(x) exp(x) + 1
>>>>> plotFx(x, f)
>>>>> 
>>>>> 
>>>>> In the case of the first function, you get:
>>>>> 
>>>>>> deparse(f)
>>>>> [1] "function (x) " "x^2"
>>>>> 
>>>>> for the second:
>>>>> 
>>>>>> deparse(f)
>>>>> [1] "function (x) " "cos(x)"
>>>>> 
>>>>> and for the third:
>>>>> 
>>>>>> deparse(f)
>>>>> [1] "function (x) " "exp(x) + 1"
>>>>> 
>>>>> 
>>>>> Thus, the "deparse(fun)[2]" snippet within the internal paste0() function
>>>>> call, gets you the second, textual part of the function body, which can
>>>>> then be passed as a character vector to the titles or other labels as
>>>>> needed.
>>>>> 
>>>>> A potential gotcha that I would envision, is that the default width in the
>>>>> character vector resulting from deparse() is 60. Thus, by default the
>>>>> function body would broken up into multiple character segments, no longer
>>>>> than approximately 60 characters each. Thus, if you envision that you might
>>>>> end up with very long formulae on x, you may need to adjust the
>>>>> width.cutoff argument in the deparse() call, and likely need to do some
>>>>> additional formatting of the labels in the plot as apropos.
>>>>> 
>>>>> There may be other functional nuances that I am missing here, but this may
>>>>> be a suitable approach.
>>>>> 
>>>>> Regards,
>>>>> 
>>>>> Marc
>>>>> 
>>>>> 
>>>>>> On Jun 6, 2019, at 2:11 PM, Bert Gunter <bgunter.4567 using gmail.com> wrote:
>>>>>> 
>>>>>> Yes, plot(z,y,..)
>>>>>> 
>>>>>> Bert
>>>>>> 
>>>>>> On Thu, Jun 6, 2019 at 9:21 AM Nick Wray <nicholas.wray using ntlworld.com>
>>>>> wrote:
>>>>>> 
>>>>>> Thanks Bert, that is exactly what I wanted.  I think that you meant
>>>>>> plot(z,y... in the last line?
>>>>>> 
>>>>>> Nick
>>>>>> 
>>>>>> On 06 June 2019 at 17:13 Bert Gunter <bgunter.4567 using gmail.com> wrote:
>>>>>> 
>>>>>> ... and if you wanted too streamline the process, something like the
>>>>>> following could be encapsulated in a function:
>>>>>> 
>>>>>> fun <- quote(exp(x))
>>>>>> z <- 1:9
>>>>>> y <- eval(fun,list(x = z) )
>>>>>> plot(x, y, main = paste("Plot of y =", deparse(fun)))
>>>>>> 
>>>>>> Further details can be found in the "Computing on the Language" section
>>>>> of
>>>>>> the "R Language Reference" manual or from suitable tutorials on the web.
>>>>>> 
>>>>>> 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 Thu, Jun 6, 2019 at 8:55 AM Nick Wray via R-help <
>>>>> r-help using r-project.org>
>>>>>> wrote:
>>>>>> 
>>>>>> Thanks but that's not quite what I meant
>>>>>> I am trying out different functions and they don't necessarily vary in a
>>>>>> regular way (like say all being powers of x where it'd be simple to just
>>>>>> have a vector for the powers you want)
>>>>>> So I might have
>>>>>> y<-x^2
>>>>>> y<-cos(x)
>>>>>> y<-exp(x+1)
>>>>>> What I am after is a way of running these functions and then calling
>>>>> each
>>>>>> one into the labelling for the appropriate graph as I plot it.  So then
>>>>> I
>>>>>> would have something like
>>>>>> mainlab<-paste("Plot of ",function in question)
>>>>>> ...? Thanks Nick
>>>>>> 
>>>>>>>> On 06 June 2019 at 16:40 Marc Schwartz < marc_schwartz using me.com> wrote:
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>>> On Jun 6, 2019, at 11:19 AM, Nick Wray via R-help <
>>>>>> r-help using r-project.org> wrote:
>>>>>>>>> 
>>>>>>>>> Is there any way of taking a line of r code (eg y<-x^2) and pasting
>>>>>> that line of code, as is, into a label, so that for example I could then
>>>>>> have a plot label "Plot of y<-x^2"?
>>>>>>>>> 
>>>>>>>>> Thanks Nick Wray
>>>>>>>> 
>>>>>>>> 
>>>>>>>> Hi,
>>>>>>>> 
>>>>>>>> See ?plotmath
>>>>>>>> 
>>>>>>>> An example:
>>>>>>>> 
>>>>>>>> x <- 1:10
>>>>>>>> y <- x^2
>>>>>>>> 
>>>>>>>> plot(x, y, main = expression(paste("Plot of ", y %<-% x^2)))
>>>>>>>> 
>>>>>>>> 
>>>>>>>> There are other incantations and examples on the help page above.
>>>>>>>> 
>>>>>>>> Regards,
>>>>>>>> 
>>>>>>>> Marc Schwartz



More information about the R-help mailing list