[R] Setting up infile for R CMD BATCH

Gang Chen gangchen6 at gmail.com
Thu Feb 9 18:42:09 CET 2012


Hi Elai, yes, the approach works out pretty well. Thanks a lot for
spending time on this and for the great help!

Gang

On Wed, Feb 8, 2012 at 5:43 PM, ilai <keren at math.montana.edu> wrote:
> I'm going to declare this SOLVED. Yes, if you don't want a separate
> script for batch, you will need to modify the original script so it
> either readline or skips it. Here is an example:
>
> # Save in file myTest.R
> ####################
> # Add this local function to the beginning of your original "program"
> and replace all the readline prompts with myreadline.
> # The new function takes on two arguments:
> # "what": the original object (in your example it was "type"<-...)
> # "prompt": The same string from readline
> # All it is doing is searching for "Answers.R", sourcing if available
> or prompting if not.
>
> myreadline <- function(what,prompt){
>  ans <- length(grep('Answers.R',list.files(),fixed=T))>0  # add a
> warning for multiple files
>  if(ans) source('Answers.R')
>  else{
>    ret <- as.integer(readline(prompt))
>    assign(what,ret,1)
>  }
> }
>
> # here is an interactive program to square only negative values
>
> print(x <- rnorm(1))
> myreadline('type','x>0 ? 1:T,2:F \n')
> print(x^type)
>
> ### END myTest.R ####
>
> Running myTest interactivly:
>
>> source('myTest.R')
> [1] -0.3712215
> x>0 ? 1:T,2:F
> 2
> [1] 0.1378054           # -.37^2
>> source('myTest.R')
> [1] 0.3160747
> x>0 ? 1:T,2:F
> 1
> [1] 0.3160747          # .316^1
>
> # Create a list of answers
>> dump('type',file='Answers.R')
>
> # run again this time with answers available
>> source('myTest.R')
> [1] -1.088665   # skips prompt
> [1] -1.088665   # -1.088^1 (type in Answer.R ==1)
>
> # Now you can also run as batch
> $ R CMD BATCH myTest.R out.R
> $ cat out.R
> # ...
>> print(x <- rnorm(1))
> [1] -1.248487
>> myreadline('type','x>0 ? 1:T,2:F \n')
>> print(x^type)
> [1] -1.248487
>
> That's it. Only thing is to keep the file names in the working
> directory straight.
>
> Enjoy
>
>
> On Wed, Feb 8, 2012 at 12:39 PM, Gang Chen <gangchen6 at gmail.com> wrote:
>> Sorry Elai for the confusions.
>>
>> Let me try to reframe my predicament. The main program "myTest.R" has
>> been written in interactive mode with many readline() lines embedded.
>> Suppose a user has already run the program once before in interactive
>> mode with all the answers saved in a text file called answer.R. Now
>> s/he does not want to go through the interactive again because it's a
>> tedious process, and would like to run the program but in batch mode
>> with answer.R. And that's why I tried the following which didn't pan
>> out:
>>
>> R CMD BATCH answer.R output.Rout
>>
>> Of couse I could rewrite a separate program specifically for batch
>> mode as you suggested previously with eval(), for example. However, is
>> there an approach to keeping the original program so that the user
>> could run both interactive and batch mode? That probably requires
>> modifying the readline() part, but how?
>>
>> Thanks,
>> Gang
>>
>>
>> On Wed, Feb 8, 2012 at 2:08 PM, ilai <keren at math.montana.edu> wrote:
>>> Gang,
>>> Maybe someone here has a different take on things. I'm afraid I have
>>> no more insights on this unless you explain exactly what you are
>>> trying to achieve, or more importantly why? That may help understand
>>> what the problem really is.
>>>
>>> Do you want to save an interactive session for future runs? then
>>> ?save.image and all your "answers" are in the environment. In this
>>> case consider putting an "if(!exists('type') | length(type)<1 |
>>> is.na(type))" before "type<- readline(...)"  in your script so type
>>> wouldn't be overwritten in subsequent runs.
>>>
>>> If your goal is to batch evaluate multiple answer files from users
>>> (why else would you ask questions with readline?), then you should
>>> have enough to go on with my answer and the examples in ?eval.
>>>
>>> Elai
>>>
>>>
>>> On Wed, Feb 8, 2012 at 9:04 AM, Gang Chen <gangchen6 at gmail.com> wrote:
>>>> Hi Elai,
>>>>
>>>> Thanks a lot for the suggestions! I really appreciate it...
>>>>
>>>> Your suggestion of using eval() and creating those answers in a list
>>>> would work, but there is no alternative to readline() with which I
>>>> could read the input in batch mode? I'm asking this because I'd like
>>>> to have the program work in both interactive and batch mode.
>>>>
>>>> Thanks again,
>>>> Gang
>>>>
>>>>
>>>> On Wed, Feb 8, 2012 at 12:50 AM, ilai <keren at math.montana.edu> wrote:
>>>>> Ahh,
>>>>> I think I'm getting it now. Well, readlines() is not going to work for
>>>>> you. The help file ?readline clearly states "In non-interactive use
>>>>> the result is as if the response was RETURN and the value is ‘""’."
>>>>> The implication is you cannot use it to "insert" different answers as
>>>>> if you were really there.
>>>>> How about using eval() instead? You will need to make the answers a
>>>>> named list (or just assigned objects).
>>>>>
>>>>> test <- expression({
>>>>>  if(a>2) print('+')
>>>>>  else print('I got more')
>>>>>  b <- b+3   # reassign b in the environment
>>>>>  print(b)
>>>>>  print(c)
>>>>>  d^2
>>>>> })
>>>>> dump('test',file='myTest.R') ; rm(test)
>>>>>
>>>>> # make the answers.R file:
>>>>>
>>>>> a=5 ; b=2 ; c=2 ; d=3
>>>>> source("myTest.R")
>>>>> eval(test)
>>>>>
>>>>> # Now, from the terminal  R CMD BATCH answers.R out.R
>>>>> # And here is my $ cat out.R
>>>>> ... flushed
>>>>>> a=5 ; b=2 ; c=2 ; d=3
>>>>>> source("myTest.R")
>>>>>> eval(test)
>>>>> [1] "+"
>>>>> [1] 5
>>>>> [1] 2
>>>>> [1] 9
>>>>>>
>>>>>> proc.time()
>>>>>   user  system elapsed
>>>>>  0.640   0.048   0.720
>>>>>
>>>>> Would this work?
>>>>> Elai
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On Tue, Feb 7, 2012 at 4:05 PM, Gang Chen <gangchen6 at gmail.com> wrote:
>>>>>> Suppose I create an R program called myTest.R with only one line like
>>>>>> the following:
>>>>>>
>>>>>> type <- as.integer(readline("input type (1: type1; 2: type2)? "))
>>>>>>
>>>>>> Then I'd like to run myTest.R in batch mode by constructing an input
>>>>>> file called answers.R with the following:
>>>>>>
>>>>>> source("myTest.R")
>>>>>> 1
>>>>>>
>>>>>> When I ran the following at the terminal:
>>>>>>
>>>>>> R CMD BATCH answer.R output.Rout
>>>>>>
>>>>>> it failed to pick up the answer '1' from the 2nd line in answers.R as
>>>>>> shown inside output.Rout:
>>>>>>
>>>>>>> source("myTest.R")
>>>>>> input type (0: quit; 1: type1; 2: type2)?
>>>>>>> 1
>>>>>> [1] 1
>>>>>>
>>>>>> What am I missing here?
>>>>>>
>>>>>> Thanks in advance,
>>>>>> Gang



More information about the R-help mailing list