Correct way to use here package with cronR scheduling - r

I've been using the here package to make my projects more portable. It works great apart from when I use cronR to schedule some of my scripts. When I run my_script.R from Rstudio I get a message from library(here):
here() starts at /home/pd/projects/my_proj
When I set script.R to run using cronR I get a different message:
here() starts at /home/pd
Which is where my_schedule.cron is stored. Ideally I want to keep my_schedule.cron where it is. I can see from the logs that my_script.R runs fine apart from when it comes to saving data because the path used by here() is incorrect. Is there anyway to get the here function to detect the project dir when my_script.R is run from cronR or the terminal?

You can modify the command cmd that is usually created with cron_rscript() by adding cd to your project folder followed by the usual part:
cmd <- "cd /home/pd/projects/my_proj && /usr/lib/R/bin/Rscript ./my_script.R >> ./my_script.log 2>&1"
cron_add(command = cmd, frequency = 'daily', at = '18:00')

If the first line of your #rstats script is wd <- here(), I will come
into your lab and SET YOUR COMPUTER ON FIRE.
Learn how to use environment variables
wd <- Sys.getenv("HOME")
wd <- file.path(wd, "projects", "my_proj")
Or use the 'Additional arguments to Rscript' element in the cronR user interface to pass something extra to the Rscript and fetch it with commandArgs().
If you don't use the cronR interface but cron_rscript, use cronR::cron_rscript(..., rscript_args = "/home/pd/projects/my_proj")
args <- commandArgs(trailingOnly = TRUE)
if(length(args) > 0){
wd <- args[1]
}

Related

How to release R's prompt when using 'system'?

I am writing an R code on a Linux system using RStudio. At some point in the code, I need to use a system call to a command that will download a few thousand of files from the lines of a text file:
down.command <- paste0("parallel --gnu -a links.txt wget")
system(down.command)
However, this command takes a little while to run (a couple of hours), and the R prompt stays locked while the command runs. I would like to keep using R while the command runs on the background.
I tried to use nohup like this:
down.command <- paste0("nohup parallel --gnu -a links.txt wget > ~/down.log 2>&1")
system(down.command)
but the R prompt still gets "locked" waiting for the end of the command.
Is there any way to circumvent this? Is there a way to submit system commands from R and keep them running on the background?
Using ‘processx’, here’s how to create a new process that redirects both stdout and stderr to the same file:
args = c('--gnu', '-a', 'links.txt', 'wget')
p = processx::process$new('parallel', args, stdout = '~/down.log', stderr = '2>&1')
This launches the process and resumes the execution of the R script. You can then interact with the running process via the p name. Notably you can signal to it, you can query its status (e.g. is_alive()), and you can synchronously wait for its completion (optionally with a timeout after which to kill it):
p$wait()
result = p$get_exit_status()
Based on the comment by #KonradRudolph, I became aware of the processx R package that very smartly deals with system process submissions from within R.
All I had to do was:
library(processx)
down.command <- c("parallel","--gnu", "-a", "links.txt", "wget", ">", "~/down.log", "2>&1")
processx::process$new("nohup", down.comm, cleanup=FALSE)
As simple as that, and very effective.

How to wait for user input in R-script ran from Windows CMD

I'm new to R and I'm stuck in a very simple task.
I want to run an R script from console, but I want the script to be able to read user inputs.
This is how I'm reading from the script:
library = readLines(n = 1L)
if(library == "1")
{
library = "GUDHI"
}
And this is how I'm running my script from R-Portable with a .bat:
#echo on
cd..
cd..
cd..
cd..
cd..
PATH C:\Users\MyUser\Desktop\App\RFolder\R-Portable\App\R-Portable\bin;%path%
cd C:\Users\MyUser\Desktop\App\RFolder
Rscript Phom.R 1
pause
When I run this .bat it throws an error (Argument is of length zero):
As if the console didn't wait for user input.
The problem is not the .bat code. If I remove the readLines functions from my script and hardcode the input, it works perfectly. I also tried the readline function with no success.
Thanks.
Solution for Interactive R script from Windows CMD:
cat("Prompt Message: ")
library = readLines(con = "stdin", 1)
I'm not sure if the prompt MUST end with ": ", but I had trouble when I removed that piece of string.
This worked for me, I hope this helps somebody.

Error in library(optparse) : there is no package called ‘optparse’

I'm trying to run some demo R code for the optparse package that I got from R-bloggers. I am using ubuntu 14.04
The code is:
#!/usr/bin/env Rscript
library(optparse)
option_list = list( make_option(c("-f", "--file"),
type="character", default=NULL,
help="dataset file name",
metavar="character"),
make_option(c("-o", "--out"),
type="character", default="out.txt",
help="output file name [default=
%default]", metavar="character")
);
opt_parser = OptionParser(option_list=option_list);
opt = parse_args(opt_parser);
if (is.null(opt$file)){
print_help(opt_parser)
stop("At least one argument must be supplied (input file).n",
call.=FALSE)
}
## program...
df = read.table(opt$file, header=TRUE)
num_vars = which(sapply(df, class)=="numeric")
df_out = df[ ,num_vars]
write.table(df_out, file=opt$out, row.names=FALSE)
If the entire script is saved in a file called yasrs.R using the call:
Rscript --vanilla yasrs.R
should return the help messages.
I get an error:
Rscript --vanilla yasrs.R Error in library(optparse) : there is no package called ‘optparse’
I have installed the package (optparse) through RStudio when writing the code and also ensured that it is installed when calling from the terminal. Both terminal and RStudio are running the same R version.
Any suggestions would be appreciated.
Where did RStudio install optparse? Get that from packageDescription("optparse").
Then check the output of .libPaths() in your Rscript environment and your RStudio environment. Maybe RStudio stuck it somewhere that RScript doesn't look.
Then check that even though they may be the same version of R, they might be two different installations. What does R.home() say in each?
One or more of these things will show you why it doesn't find it. Solution is probably to write and run a little RScript that installs it, then you should be fairly sure its going to go in a location that RScript will find it in future.

Exporting .csv from R & Batch file

I run a report in R every morning and I'm trying to automate this task. I have a Windows machine and I've created a task within Task Scheduler. I can get the file to run at a certain time, but I can't get it to export the csv. My initial thoughts is that there is a disconnect between forward- & back-slashes, but I'm not sure where the break is. Anyone have any thoughts?
R_script.R
setwd('C:/Users/Me/Desktop')
x <- runif(5)
y <- runif(5)
xy <- data.frame(X = x, Y = y)
write.csv(xy, 'C:/Users/Me/Desktop/xy.csv')
Batch File
Rscript CMD BATCH
C:\Users\Me\R_script.R
Try running the first line of your batch file in a cmd window. It results in an error:
>Rscript CMD BATCH
Fatal error: cannot open file 'CMD': No such file or directory
And if you use R CMD BATCH it doesn't detect the input file because they should be on the same line:
>R CMD BATCH
no input file
Instead run the command in one of these two ways, with the file path on the same line:
>Rscript C:\Users\Me\R_script.R
>R CMD BATCH C:\Users\Me\R_script.R

R and System calls

I have used R in the past to do very basic calls to the commmand line. The example can be found here.
This time around, I am looking to mimic this code which runs successfully from the command line in Windows:
> cd C:\Documents and Settings\BTIBERT\My Documents\My Dropbox\Eclipse\Projects\R\MLB\retrosheet\rawdata
> bgame -y 2010 2010bos.eva >2010bos.txt
This is the code I am trying to run inside of R. I have already set the working directory inside of R.
dir <- paste("cd", getwd(), sep=" ")
system(dir)
system("bgame -y 2010 2010bos.eva >2010bos.txt")
I am sure this is user error, but what am I doing wrong? It appears to work initially, but returns the following error. I very well could be doing something wrong, but I believe I am using the same commands.
Expanded game descriptor, version 109(185) of 05/08/2008.
Type 'bgame -h' for help.
Copyright (c) 2001 by DiamondWare.
[Processing file 2010bos.eva.]
>2010bos.txt: can't open.
Warning message:
running command 'bgame -y 2010 2010bos.eva >2010bos.txt' had status 2
Any help you can provide will be appreciated.
You need to issue all commands in one system() call:
system(paste("cd",getwd() "&& bgame -y 2010 2010bos.eva >2010bos.txt",sep=" "))
You should already be in your working directory, so I'm not sure the cd getwd() is necessary. And you may need quotes around your path because it contains spaces. The error may be resolved by putting spaces around >.
If I were in your shoes, I would try this:
system("bgame -y 2010 2010bos.eva > 2010bos.txt")
UPDATE:
And you should probably heed this advice in the "Differences between Unix and Windows" section of ?system that says you should use shell:
• The most important difference is that on a Unix-alike
‘system’ launches a shell which then runs ‘command’. On
Windows the command is run directly - use ‘shell’ for an
interface which runs ‘command’ _via_ a shell (by default the
Windows shell ‘cmd.exe’, which has many differences from the
POSIX shell).
This means that it cannot be assumed that redirection or
piping will work in ‘system’ (redirection sometimes does, but
we have seen cases where it stopped working after a Windows
security patch), and ‘system2’ (or ‘shell’) must be used on
Windows.
Has no-one else found that system("dir", intern = T) for example doesn't work, but that you need system("cmd.exe /c dir", intern = T)? Only the latter works for me. I found this at the discussion site here (William Dunlap's post, about a third of the way down).
Also, it doesn't work with the "cd" command, but you can use the setwd() function within R and then the command will be executed within that directory.
I created the following functions for convenience, for executing programmes and running commands:
#the subject is an input file that a programme might require
execute <- function(programme, subject.spec = "", intern = FALSE, wait = FALSE){
if(!identical(subject.spec, "")){subject.spec <- paste0(" ", subject.spec)} #put space before the subject if it exists
system(paste0("cmd.exe /c ", programme, subject.spec), intern = intern, wait = wait)
}
command <- function(command, intern = TRUE, wait = FALSE){
system(paste("cmd.exe /c", command), intern = T, wait = wait)
}
Does it break your code when you get error 1 or does execution continue?
Whenever executing system commands through another language it is useful to print the system call before you call it to see exactly what is happening, pull up the shell you are intending to use and check for the same error. As the command is executed correctly this could be a hickup in bgame or R.
If you look at http://astrostatistics.psu.edu/datasets/R/html/base/html/shell.html you can see the variable flag passed to the system call."flag the switch to run a command under the shell. If the shell is bash or tcsh the default is changed to "-c"."
Also "the shell to be used can be changed by setting the configure variable R_SHELL to a suitable value (a full path to a shell, e.g. /usr/local/bin/bash)."

Resources