[R] assign if not set; stand-alone R script, source'able too?

Alexy Khrabrov deliverable at gmail.com
Tue Nov 20 02:22:02 CET 2007


Marc -- thanks, very interesting.

I was in fact tinkering at a very simple default arguments assignment  
to a generic command-line R script header:

#!/bin/sh
# graph a fertility run
tail --lines=+4 "$0" | R --vanilla --slave --args $*; exit
args <- commandArgs()[-(1:4)]

# the krivostroi library
source("/w/ct/r/kriv/krivostroi.r")

# NB: vector assignment in R? defaults?
file    <- args[1]
maxruns <- if (is.na(args[2])) 1 else args[2]
prefix  <- if (is.na(args[3])) file.basename(file) else args[3]

-- turns out, args[N] here are NA if not supplied on the command- 
line.  I'd like to see a nicer way to do it still, without repeating  
args[N] twice for each assignment though.


Another thing from this snippet, unrelated to assignment, is that was  
the only way to get R script to be packed in a single file runnable  
from the command line in a stand alone way.  Yet when I want to source 
() it, R obviously chokes on the shell command tail.  My previous  
solution was to have a pair of files, script.r/script.sh for each R  
script, where .sh would look like

echo "argv <- c('$1','$2'); source('main.r')" | R --vanilla --slave

Wonder if there's a way to have a single file which is a stand-alone  
command script, and can be source()'d in R.

Cheers,
Alexy

On Nov 20, 2007, at 4:03 AM, Marc Schwartz wrote:
>
> On Tue, 2007-11-20 at 03:32 +0300, Alexy Khrabrov wrote:
>> What's the idiom of assigning a default value to a variable if it's
>> not set?  In Ruby one can say
>>
>> v ||= default
>>
>> -- that's an or-assign, which triggers the assignment only if v is  
>> not set already.  Is there an R shorthand?
>>
>> Cheers,
>> Alexy
>
> If 'v' is not set, then it does not exist, hence you can use exists 
> () to
> check for it. However, you need to [potentially] distinguish where the
> variable might be located. Keep in mind that R uses lexical scoping,
> hence the exists() function has other arguments to define where to  
> look.
>
> A simple example:
>
>> v
> Error: object "v" not found
>
> if (!exists("v")) v <- "Not Set"
>
>> v
> [1] "Not Set"
>
> v <- "Set"
>
> if (!exists("v")) v <- "Not Set"
>
>> v
> [1] "Set"
>
>
> See ?exists for more information.
>
> That being said, just as an example of extending R, you could do the
> following, which is to create a new function %||=% (think %in% or %*%)
> which can then take two arguments, one preceding it and one following
> it, and then basically do the same thing as above. Again here, scoping
> is critical.
>
>
> "%||=%" <- function(x, y)
> {
>   Var <- deparse(substitute(x))
>   if (!exists(Var))
>     assign(Var, y, parent.frame())
> }
>
>> v
> Error: object "v" not found
>
> v %||=% "Not Set"
>
>> v
> [1] "Not Set"
>
> v <- "Set"
>
> v %||=% "Not Set"
>
>> v
> [1] "Set"



More information about the R-help mailing list