# [R] Coding problem: How can I extract substring of function call within the function

Martin Maechler maechler at stat.math.ethz.ch
Fri Aug 14 09:06:55 CEST 2009

```>>>>> "PJ" == Pitt, Joel <pittj at georgian.edu>
>>>>>     on Thu, 13 Aug 2009 18:40:49 -0400 writes:

> As I said in my original email, I'm sure that many of
> you will doubt the wisdom of what I'm trying to do --
> and I certainly share some of your misgivings. I have
> misgivings too about the use of "training wheels" for
> bicycles, but they are clearly useful for some people,
> and, in this instance, I think that smoothing students
> passage over what I have seen to be genuine stumbling
> blocks for them outweighs the drawbacks.

Very good!  I like the comparison with  "training wheels"...
Having been both a dad with wonderful boys "on training wheels"
and a longtime teacher of S and R (and statistics).

One property of the bike on training wheels (=: TW) is that every child,
probably even before they first mount a bike with TWs,
knows that the training wheels are a substitute for the kid's
not-yet perfect own balance, and whenever they are on their TW
bike, they at least subconsciously are aware that they are in
fact training for the "real" bicycle experience.

If we translate this to the teaching of R,
I come -- very strongly, indeed -- to the same conclusion as Gabor,
that you should call your functions differently, e.g. 'Mean'
or 'mean2' {{or ;-)  'meanGA', the Georgia version of mean ;-)}}
so the training wheels remain visible to your students.

Best regards,
Martin Maechler,  ETH Zurich

>  I am not merely changing defaults -- if that was all I
>  believe I would be doing students a disservice. My version of
>  mean doesn't merely return a value in the presence of missing
>  values, it prints a warning if missing values are pressent. I
>  think the one step with my version

>> mean(x) # my version
> Warning: x has 3 missing values.  [1] 51.69388
>> base::mean(x)
> [1] NA
>> length(x[is.na(x)]) # oops, some missing values, I wonder
>> how many?
> [1] 3 # not too bad, let's look find the mean without
> them
>> base::mean(x,na.rm=T)
> [1] 51.69388

> It has some other useful features which I needn't go
> into here.

> I have not yet used this package but plan to use it in
> my classes this fall, and I thought about using
> alternate names for my function versions (Mean vs. mean,
> Table vs. table, Hist vs. hist -- John Fox does that in
> his Rcmdr) but decided against it. I believe that by
> carefully explaining the difference between the versions
> in my package and the standard versions students will be
> able to adjust to using the standard version if and when
> they need or choose to.

> I have considerable experience using R in both
> introductory and moderately advanced classes, and
> despite my enthusiasm for it have had at best very mixed
> success. I am certainly not unique in belief that by
> making initial exposure to R fit more closely to student
> needs we will create more real R users in the long
> run. Clearly the several different versions of
> menu-driven front ends have the same goal. Since I
> believe the R console is the right environment for
> exploratory data analysis I prefer to avoid the menu
> driven detour.

> Regards, Joel

> ________________________________

> From: Gabor Grothendieck
> [mailto:ggrothendieck at gmail.com] Sent: Thu 8/13/2009
> 5:19 PM To: Pitt, Joel Cc: r-help at r-project.org Subject:
> Re: [R] Coding problem: How can I extract substring of
> function call within the function

> The Defaults package can be used to change the defaults
> of functions and reset them back.

> There is some question on whether all this is advisable.
> It will invalidate any books, documentation, examples in
> the help files that come with R and other resources on R
> that they might have otherwise used by introducing
> deliberate differences.  Later, to learn standard R it
> will be harder since they will have to unlearn what they
> learned.

> If you really must do this I would suggest using
> different names, e.g. mean2 or Mean, so its clear one is
> using non-standard versions.  In that case you don't
> need rStd in the first place.

> Even better, perhaps a one page cheat sheet of common
> forms would be better than a package full of trivially
> and annoyingly changed functions, e.g.

> mean(x, na.rm = TRUE) # mean of non-missings in x
> barplot(x, beside = TRUE) # bar chart placing bars
> beside each other

> On Thu, Aug 13, 2009 at 4:48 PM, Pitt,
> Joel<pittj at georgian.edu> wrote:
>> In order to ease my students into the R environment I am
>> developing a package which installs a variety of utility
>> functions as well as slightly modified versions of some
>> standard R functions -- e.g. mean, hist, barplot, .... In
>> my versions of these standard R functions I either add
>> options or alter some defaults that seem to create
>> difficulties for most of my students -- for example, when
>> they do barcharts for two dimensional tables they
>> generally want the bars to be side-by-side and stumble
>> over the standard default of besides=F, and my version of
>> mean by default reports a mean value in the presence of
>> NA's after warning of that presence (but retains the
>> option of setting na.rm=F). (I don't doubt that some (if
>> not many) of you will doubt the wisdom of this, and I
>> would be happy to discuss this in more detail on other
>> occasions.) You might want to think of my replacement R
>> functions as a kind of "training wheels" for R, and, in
>> the spirit of training wheels I include a funct!  ion in
>> my package that allows a user to revert to the standard
>> package (and loosing its additional
>> functionality). However, I want to add a function that
>> allows a user to revert to running the standard R version
>> of a given function on a one-off basis and that's where
>> my problem comes up.
>>
>> I believe that it should be possible to write a function
>> rStd with the usage rStd(x,...) where x is a function --
>> e.g. mean, hist, barchart, and the remaining parameters
>> would be any of the parameters that should be passed to
>> the unmodified version of mean, hist, barchart... The
>> problem I have is how to get ahold of that collection of
>> parameters as a single character string. Now I know that
>> sys.calls()[[1]] will give me the full text of the
>> initial call, but the problem is to detach the ... above
>> from that as a text string. If I could do that I'd be
>> done.
>>
>> Here's the incomplete code with comments -- see the gap
>> set off by astericks.
>>
>> rStd=function(x,...){ if(missing(x)) # must have a
>> specified function { cat("Error: No function
>> specified\n"); return(invisible(NULL)); }
>> z=as.character(substitute(x));
>> # must include code here to check that z is the name of
>> # one of our altered functions if z is an altered
>> # function, e.g., "mean" then concatenating "x" with z
>> # gives the overlaid function -- e.g. xmean is the
>> # standard mean
>> #***************************************************************************
>> # Now we need to get a hold of the ... text *
>> #                                                                                             *
>> w=sys.calls()[[1]]; # this gets me the whole text of the
>> call *
>> #                                                                                             *
>> # and now here's where the problem arises * how to I get
>> # the ... text if I could get it and say * assign it to
>> # the variable params * I could then set *
>> #                                                                                             *
>> cmd=sprintf("x%s(%s)",z,params) # see remarks above about
>> z # and then it's done....
>> eval(parse(text=cmd),sys.frame()); }
>>
>>
>> Any help would be much appreciated.
>>
>> Regards Joel Joel Pitt, Ph.D.  Associate Professor &
>> Chair Mathematics & Computer Science Georgian Court
>> University 900 Lakewood Avenue Lakewood, NJ 08540
>> 732-987-2322

```