Re: [S] deparse+substitute (simple solution ?)

Paul Quataert (Paul.Quataert@ihe.be)
Thu, 7 May 1998 09:14:33 MET-1METDST


A few weeks ago I asked how to extend the use of the
deparse + substitute combination (for the original question
see below).

Thanks to everybody who gave me some suggestions and/or
solutions.

Trying to understand the remarks resulted in following
one-liner (for friends and enemies !). However it seems to
depend on a particular platform (S 3.2 and S 4.0, Windows
NT). Can anybody explain me ? Is it particular to my configuration ?

# # # # #
# FUNTION: CAPTURE ARGUMENTS (caparg.my)
# ARGUMENTS:
# ANAM: allows to specify which argument(s) to be captured
# (if ANAM is not given, all arguments in ... are displayed)
#
# WHERE: in which frame to look; to cope with difference
# between platforms/configurations:
# - for S+ 3.2 WHERE=2 seems to work to capture the original
# - for S+ 4.0 WHERE=5 is necessary for the original function
# if this is a particularity of my specific configuration is
# not yet clear to me ... (S+ 4.0 is just installed)
# ... : all other arguments

caparg.my_function(ANAM=names(sysc)[-1],WHERE=2,...)
as.character((sysc_sys.call(WHERE))[ANAM])

# # # # # #

# COMMENTS
Above function is based on the observation that sys.call(2)
gives the original call (in Splus 3.2). So the solution it to make
the appropriate selection of the arguments.

However under Splus 4.0 there are some extra overhead in between
the frame between the expression level and the call to the original
function. Why these frames are necessary and if it is a particularity
of my personal configuration is yet not clear to me. Up to now I did
not find any information about them. They contain information as
..C "S_api_get_message" and .Sapi.build.out

Another problem is it cannot discriminate between xv=NULL
and xv not given at all in the argument list. In both situations
"NULL" is given.

# EXAMPLES

Suppose:
tst3_function(...) caparg.my(c('xv','yv'),...)
tst2_function(...) tst3(...)
tst1_function(...) tst2(...)
a_list()

Then:
tst1(xv=1:5) # "1:5" "NULL"
tst1(yv=letters) # "NULL" "letters"
tst1(xv=NULL) # "NULL" "NULL"
tst1(xv=a,yv=list(),wv=1:5) # "a" "list()"
# wv not given because not specified in ANAM

However suppose:
tstX_function(...) caparg.my(...)

Then:
# (1) ALL arguments
tstX(xv=a,yv=list(),zv=1:5,wv=letters)
# "a" "list()" "1:5" "letters"

# (2) SPECIFIC arguments
tstX(ANAM=c('zv','xv'),xv=a,yv=list(),zv=1:5,wv=letters)
# "1:5" "a"

# (3) MISSING elements
tstX(ANAM=c('zv','xv','tv'),xv=a,yv=list(),zv=1:5,wv=letters)
# "1:5" "a" "NULL"

### NOTE: ORIGINAL QUESTION

I want to use the deparse(substitute()) combination
to create labels, e.g.
tstS <- function(xv) deparse(substitute(xv))
Then I get for
tstS(letters)
[1] "letters"

Everything is OK for now. However this trick does not
work anymore when I use tstS as a subroutine in another
procedure, e.g.
tstM <- function(...) tstS(...)
Then I get
tstM(xv=letters)
[1] "..1"
which is the name of the variable in tstM, and not the
name of the original variable.

Does there exist a DIRECT way to fix this problem ?
Paul Quataert
Scientific Instititute of Public Health, Louis Pasteur
(formerly I.H.E. Institute of Hygiene and Epidemiology
Department of Epidemioly
J. Wytsmanstraat 14
1050 BRUSSEL

tel. +32-2-642 54 02 fax. +32-2-642 54 10
-----------------------------------------------------------------------
This message was distributed by s-news@wubios.wustl.edu. To unsubscribe
send e-mail to s-news-request@wubios.wustl.edu with the BODY of the
message: unsubscribe s-news