[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