I want to run a R code in batch and wait for user input - r

I want to run a program in batch and I want it to wait for the user input in the program.
This is what I have:
library('XLConnect')
FolderPath<-"C:/Documents/Testing/"
load(paste('C:/Documents/Testing/Program.ml',sep=''));Run()
This code is named Test.R, and it calls a compiled file that runs a function that does what I need. I need to have some inputs in this exercise, so I wanted to ask for the user to input some dates.
The program should do something like this:
What are the years for this simulation?
Then the user enter:
>2001, 2002, 2003, 2004
The program will save this vector in variable, lets call y.
Then, when I load the compiled function, I will use y.
The problem is that I run this R code in cmd batch.

Yukio, try the function readline (documentation here) as in the following example, in which a user inputs two years separated by a comma.
> years = readline('What are the years for this simulation? ')
What are the years for this simulation? 2001, 2002
> years = as.numeric(unlist(strsplit(years, ",")))
> years
[1] 2001 2002
By the way, your English is great!

As far as I understand (someone please correct me if this is wrong), but you can't send messages to the user at the command line when executing a script with R CMD BATCH (it writes all input and output to an .Rout file). But executing a script with Rscript.exe does in fact let you send stuff to stdout. However, in order to get input from a user when executing with Rscript.exe, you need to use file('stdin') as the connection to your input function, which, funny enough, won't work if you then try to run the script from the R interpreter with the source function. Here's an example that showing you how to prompt the user for a series of comma separated years, regardless of whether the script runs with Rscript.exe or the source function in interactive mode.
con <- if (interactive()) stdin() else file('stdin')
message('what are the years')
years <- scan(file=con, sep=',', nlines=1, quiet=TRUE)
print(years)

You can deal easily with user inputs in a batch file not in the R.
You create a batch file , say launcher.bat , like this for example
ECHO I am Rscript launcher
set /p years= What are the years for this simulation?
cd R_SCRIPT_PATH
Rscript youscript.R %years%
The user can write as many years he want, it will go in the variable years. Then in your script you parse this variable to set it as a valid list of years.

Related

Loop program with commands to other programs

I have these lines of code in one program:
source("R:/ML NC8 MENSAL.R")
source("R:/ ML NPC NC8 MENSAL.R")
The mentioned programs both have these lines of code:
# Defining Variable
MONTH <- "01_2021"
I want to make this definition in the first program for the two programs.
Which code should I write?
Thank you for your help.
If both scripts have these lines and you only want to return it from the first script, then I would write a function in both scripts. Only the first one would return the month-value.
month_return_scr1 <- function(){
MONTH <- "01_2021"
#more code
return(list(MONTH, more variables, or data.frames)}
month_return_scr2 <- function(){
MONTH <- "01_2021"
#more code
return(list(more variables, or data.frames)}
The Month would then not be returned by the second source.
I used successfully the following solution:
Create a program - R:/constants.R - with the month variable (and any
others used in all programs)
Create a program - R:/superprogram.R - that executes all the 23 programs
In each 23 programs replace the variables definition for this code
source("R:/constants.R"). This will bring the constants defined in
the source file into the global environment.
Change the variables in program R:/constants.R and save it
Run R:/superprogram.R

Is there a way to check where R is 'stuck' within a for loop? (R)

I am using system() to run several files iteratively through a program via CMD. It deposits each outputs into a sub-directory designated for specifically and only that input file. So # of inputs is exactly equal to the number of output directories/outputs.
My code works for the first iteration, but I can see in the console that it won't move on to the second file after completing the first. The stop sign remains active so I know R is still 'running', but since the for loop environment is unique I can't really tell what it's stuck on. It just stays like this for hours. Therefore I'm not sure how to begin to diagnose the issue I'm having. Is there a way of tracing what happened after cancelling the code, for example?
If your curious, the code looks like this btw. I don't know how to make it reproducible, so I just commented each line:
for (i in 1:length(flist)) {
##flist is a vector of character strings. Each
row of characters is both the name of the input file and the name of the
output directory
setwd(paste0(solutions_dir, "\\", flist[i]))
#sets the appropriate dir
system(paste0(program_dir,"\\program.exe I=",
file_dir, "\\", flist[i], " O=",solutions_dir, "\\", flist[i],
"\\solv"))
##line that inputs program's exe file and the appropriate input/output
locations
}

R system() error when using brace expansion to match folders in linux

I have a series of sequential directories to gather files from on a linux server that I am logging into remotely and processing from an R terminal.
/r18_060, /r18_061, ... /r18_118, /r18_119
Each directory is for the day of year the data was logged on, and it contains a series of files with standard prefix such as "fl.060.gz"
I have to supply a function that contains multiple system() commands with a linux glob for the day. I want to divide the year into 60-day intervals to make the QA/QC more manageable. Since I'm crossing from 099 - 100 in the glob, I have to use brace expansion to match the correct sequence of days.
ls -d /root_driectory/r18_{0[6-9]?,1[0-1]?}
ls -d /root_driectory/r18_{060..119}
All of these work fine when I manually input these globs into my bash shell, but I get an error when the system() function provides a similar command through R.
day_glob <- {060..119}
system(paste("zcat /root_directory/r_18.", day_glob, "/fl.???.gz > tmpfile", sep = "")
>gzip: cannot access '/root_directory/r18_{060..119}': No such file or directory
I know that this could be an error in the shell that the system() function operates in, but when I query that it gives the correct environment and user name
system("env | grep ^SHELL=")
>SHELL=/bin/bash
system("echo $USER")
>tgw
Does anyone know why this fails when it is passed through R's system() command? What can I do to get around this problem without removing the system call altogether? There are many scripts that rely on these functions, and re-writing the entire family of R scripts would be time prohibitive.
Previously I had been using 50-day intervals which avoids this problem, but I thought this should be something easy to change, and make one less iteration of my QA/QC scripts per year. I'm new to the linux OS so I figured I might just be missing something obvious.

R: I fail to pause my code

I am trying to pause my code for a little while, time for me to observe the plots.
I tried:
print('A')
something = readline("Press Enter")
print('B')
print('C')
, then there is no pause, the line print('B') is fed to readline and get stored into something and therefore only A and C got printed on the screen. Note that if I add an empty line between Something = readline("Press Enter") and print("B"), then print("B") get printed on the screen but still the console doesn't allow the user to press enter before continuing.
And I tried:
print('A')
Sys.sleep(3)
print('B')
print('C')
The program waits 3 seconds before starting and then run "normally" without doing any pause between print('A') and print('B').
What do I missunderstand?
Here is my R version: R 3.1.1 GUI 1.65 Snow Leopard build (6784)
The problem with readline is that if you paste your script into an R console, or execute it from eg Rstudio, the redline function is read and then the next line of the script is read in as the console entry, which in your case sets the value of something to print('B).
An easy way to get around this is to stick your entire code in a function, then call the function to run it. So, in your case:
myscript = function(){
print('A')
something = readline(prompt = "Press Enter")
print('B')
print('C')
}
myscript()
The output of this for me (in Rstudio, with R version 3.1.1):
[1] "A"
Press Enter
[1] "B"
[1] "C"
This has always felt like a bit of a hack to me, but it's essentially what the readline documentation recommends in its example.
I've never used sleep in my code, so I can't help you there.
Edit to clarify based on comments: This will only work if myscript() is the very last line of your script, or if it is manually entered into the console after running the script to generate the function. Otherwise, you will run into the same problem as before- the next line of code will be automatically entered.

Kill a calculation programme after user defined time in R

Say my executable is c:\my irectory\myfile.exe and my R script calls on this executeable with system(myfile.exe)
The R script gives parameters to the executable programme which uses them to do numerical calculations. From the ouput of the executable, the R script then tests whether the parameters are good ore not. If they are not good, the parameters are changed and the executable rerun with updated parameters.
Now, as this executable carries out mathematical calculations and solutions may converge only slowly I wish to be able to kill the executable once it has takes to long to carry out the calculations (say 5 seconds)
How do I do this time dependant kill?
PS:
My question is a little related to this one: (time non dependant kill)
how to run an executable file and then later kill or terminate the same process with R in Windows
You can add code to your R function which issued the executable call:
setTimeLimit(elapse=5, trans=T)
This will kill the calling function, returning control to the parent environment (which could well be a function as well). Then use the examples in the question you linked to for further work.
Alternatively, set up a loop which examines Sys.time and if the expected update to the parameter set has not taken place after 5 seconds, break the loop and issue the system kill command to terminate myfile.exe .
There might possibly be nicer ways but it is a solution.
The assumption here is, that myfile.exe successfully does its calculation within 5 seconds
try.wtl <- function(timeout = 5)
{
y <- evalWithTimeout(system(myfile.exe), timeout = timeout, onTimeout= "warning")
if(inherits(y, "try-error")) NA else y
}
case 1 (myfile.exe is closed after successfull calculation)
g <- try.wtl(5)
case 2 (myfile.exe is not closed after successfull calculation)
g <- try.wtl(0.1)
MSDOS taskkill required for case 2 to recommence from the beginnging
if (class(g) == "NULL") {system('taskkill /im "myfile.exe" /f',show.output.on.console = FALSE)}
PS: inspiration came from Time out an R command via something like try()

Resources