Running R function with arguments in 32 bit R, inside 64 bit R - r

Suppose I want to run the function
test.function <- function(arg1){
print(arg1)
}
How can I run, lets say:
test.function("Hello world")
in 32 bit mode, using 64 bit R? I have managed running an entire script in 32 bit mode using
system(paste0(Sys.getenv("R_HOME"), "/bin/i386/Rscript.exe ",'"some_script.R"'))
But how can I change this, so that it can run a function with arguments, instead of an entire script?
EDIT
Following the answer by Roman Luštrik and running
system('Rscript test.script.R "hello"')
Gives me the following error:
Error in winDialog(type = "ok", message = message_text) :
winDialog() cannot be used non-interactively
call: -> check.for.updates.R -> winDialog
Running stopped
Warning message:
running command 'Rscript test.script.R "hello"' had status 1
(The error message was in my native language, so I had to translate a few words, so the text might differ slightly on other systems)

You can't run a specific function only, you will have to create a script. This does not stop you from creating a one-function only script, though.
If you create a script called test.script.R and put it somewhere where you can find it.
args <- commandArgs(trailingOnly = TRUE)
str(args)
test.function <- function(x) {
message("Your input:")
message(x)
}
invisible(sapply(args, test.function))
Open up a terminal window. You can use Windows' cmd.exe (press Windows key and type cmd.exe or Command Prompt or whatever you have in your perhaps localized version of the system). Navigate to where the script is located and run it using the below command.
$ Rscript test.script.R "hello" "hello" "won't you tell me your name" "i hate the doors"
chr [1:4] "hello" "hello" "won't you tell me your name" ...
Your input:
hello
Your input:
hello
Your input:
won't you tell me your name
Your input:
i hate the doors
Or, you could use system to do the same thing through R.
system('Rscript test.script.R "hello" "hello" "won't you tell me your name" "i hate the doors"')
Notice the way I use single and double quotes. Single quotes are on the outer side. This call also assumes the script is located in the workspace where R is currently looking. You can change that using setwd(), though.

I managed to find a solution myself, by modifying Roman Luštrik's solution.
Following his example we have the script called test_script.R:
args <- commandArgs(trailingOnly = TRUE)
test.function <- function(x) {
print(x)
}
args.run <- list(x = args)
mydata <- do.call(test.function, args = args.run)
save(mydata, file = "Data.Rda") # If you need the output to an R object
Then in another script that runs 64 bit R, we can run this function in 32 bit R by:
pathIn32BitRScript <- '"C:/Some path/test_script.R"'
system(paste0(Sys.getenv("R_HOME"), "/bin/i386/Rscript.exe", pathIn32BitRScript, " ", "Hello world") )
load("Data.Rda") # Loads the results into an object called mydata
invisible(file.remove("Data.Rda")) # Deletes the file we created
In this example we have x = "Hello World". In case you have spaces in your path you will need the double quotes as I have in this example.

Related

Is there a way to debug an R script run from the command line with Rscript.exe

Is it possible to debug an R source file which is executed with Rscript.exe?
> Rscript.exe mysource.R various parameters
Ideally, I would like to be able to set a break-point somewhere in the mysource.R file in RStudio.
Is entering the R debugger directly at the command line possible for instance by adding some debug directive to the source file?
Maybe sourcing the file from R would work? How? How do I pass the command line arguments "various parameters" so that commandArgs() returns the correct values?
The mysource.R could look as follows (in practice it is much more complicated).
#!/usr/bin/Rscript
args <- commandArgs(trailingOnly=TRUE)
print(args)
As far as debugging from console is concerned there are few questions related to it without an answer.
Is there a way to debug an RScript call in RStudio? and Rscript debug using command line
So, I am not sure if something has changed and if it is now possible.
However, we can debug from sourcing the file by using a hack. You could add browser() in the file wherever you want to debug. Consider your main file as :
main.R
args <- commandArgs(trailingOnly=TRUE)
browser()
print(args)
Now, we can override the commandArgs function and pass whatever arguments we want to pass which will be passed when you source the file.
calling_file.R
commandArgs <- function(...) list(7:9, letters[1:3])
source("main.R")
After running the source command, you could debug from there
Called from: eval(ei, envir)
#Browse[1]> args
#[[1]]
#[1] 7 8 9
#[[2]]
#[1] "a" "b" "c"
There's no native way to debug Rscript in the command line, but you can use a kind of hacky workaround I whipped up with readLines and eval.
ipdb.r <- function(){
input <- ""
while(!input %in% c("c","cont","continue"))
{
cat("ipdb.r>")
# stdin connection to work outside interactive session
input <- readLines("stdin",n=1)
if(!input %in% c("c","cont","continue","exit"))
{
# parent.frame() runs command outside function environment
print(eval(parse(text=input),parent.frame()))
}else if(input=="exit")
{
stop("Exiting from ipdb.r...")
}
}
}
Example usage in an R file to be called with Rscript:
ipdbrtest.R
a <- 3
print(a)
ipdb.r()
print(a)
Command line:
$ Rscript ipdbrtest.R
[1] 3
ipdb.r>a+3
[1] 6
ipdb.r>a+4
[1] 7
ipdb.r>a <- 4
[1] 4
ipdb.r>c
[1] 4
If you're considering using R instead of Rscript, you could pass it environment variables and retrieve them with Sys.getenv().

Interactive Debugging in R

I have a toy R script (test.R) as follows:
myString <- "Hello World"
browser()
print(myString)
I want to interactively debug the script, hence the 'browser()' call.
However, when I run the script like this:
Rscript test.R
I just see:
Called from: top level
[1] "Hello World"
i.e. the 'browser()' call seems to get skipped. When I run the script like this:
R -f test.R
I see:
>
> myString <- "Hello World"
> browser()
Called from: top level
Browse[1]> print (myString)
[1] "Hello World"
Browse[1]>
>
But, execution does not stop at 'Browse[1]>' to allow me to debug.
What am I missing here? In python, I can insert "import pdb; pdb.set_trace()" to debug. I am looking for something similar in R.
See this for how to use browser(). You will be able to source('scriptname.R') a script in the R interactive environment on terminal (by running R instead of Rscript scriptname.R) and then browser() will behave very similar to import pdb; pdb.set_trace() . The one major caveat is arguments - you could manually configure that to use the arguments you would supply on the command line by using say if(interactive()) (or there might be other ways to achieve this).

Error when running (working) R script from command prompt

I am trying to run an R script from the Windows command prompt (the reason is that later on I would like to run the script by using VBA).
After having set up the R environment variable (see the end of the post), the following lines of code saved in R_code.R work perfectly:
library('xlsx')
x <- cbind(rnorm(10),rnorm(10))
write.xlsx(x, 'C:/Temp/output.xlsx')
(in order to run the script and get the resulting xlsx output, I simply type the following command in the Windows command prompt: Rscript C:\Temp\R_code.R).
Now, given that this "toy example" is working as expected, I tried to move to my main goal, which is indeed very similar (to run a simple R script from the command line), but for some reason I cannot succeed.
Again I have to use a specific R package (-copula-, used to sample some correlated random variables) and export the R output into a csv file.
The following script (R_code2.R) works perfectly in R:
library('copula')
par_1 <- list(mean=0, sd=1)
par_2 <- list(mean=0, sd=1)
myCop.norm <- ellipCopula(family='normal', dim=2, dispstr='un', param=c(0.2))
myMvd <- mvdc(myCop.norm,margins=c('norm','norm'),paramMargins=list(par_1,par_2))
x <- rMvdc(10, myMvd)
write.table(x, 'C:/Temp/R_output.csv', row.names=FALSE, col.names=FALSE, sep=',')
Unfortunately, when I try to run the same script from the command prompt as before (Rscript C:\Temp\R_code2.R) I get the following error:
Error in FUN(c("norm", "norm"))[[1L]], ...) :
cannot find the function "existsFunction"
Calls: mvdc -> mvdcCheckM -> mvd.has.marF -> vapply -> FUN
Do you have any idea idea on how to proceed to fix the problem?
Any help is highly appreciated, S.
Setting up the R environment variable (Windows)
For those of you that want to replicate the code, in order to set up the environment variable you have to:
Right click on Computer -> Properties -> Advanced System Settings -> Environment variables
Double click on 'PATH' and add ; followed by the path to your Rscript.exe folder. In my case it is ;C:\Program Files\R\R-3.1.1\bin\x64.
This is a tricky one that has bitten me before. According to the documentation (?Rscript),
Rscript omits the methods package as it takes about 60% of the startup time.
So your better solution IMHO is to add library(methods) near the top of your script.
For those interested, I solved the problem by simply typing the following in the command prompt:
R CMD BATCH C:\Temp\R_code2.R
It is still not clear to me why the previous command does not work. Anyway, once again searching into the R documentation (see here) proves to be an excellent choice!

Running R function as command line script with arguments

Lets say I have the following script
k <- as.numeric(readline("Start Index: "))
tot <- NULL
for (i in 1:k){
tot <- c(tot, i)
}
write.csv(tot, "test.csv")
I would like to run this script from the command line. How can I run it so that it still asks for the user input (k). Or otherwise can I add the value of k in the CMD command as argument? I am on Linux.
You might find the information in ?commandArgs helpful.
From the description:
Provides access to a copy of the command line arguments supplied
when this R session was invoked.

Getting path of an R script

Is there a way to programmatically find the path of an R script inside the script itself?
I am asking this because I have several scripts that use RGtk2 and load a GUI from a .glade file.
In these scripts I am obliged to put a setwd("path/to/the/script") instruction at the beginning, otherwise the .glade file (which is in the same directory) will not be found.
This is fine, but if I move the script in a different directory or to another computer I have to change the path. I know, it's not a big deal, but it would be nice to have something like:
setwd(getScriptPath())
So, does a similar function exist?
This works for me:
getSrcDirectory(function(x) {x})
This defines an anonymous function (that does nothing) inside the script, and then determines the source directory of that function, which is the directory where the script is.
For RStudio only:
setwd(dirname(rstudioapi::getActiveDocumentContext()$path))
This works when Running or Sourceing your file.
Use source("yourfile.R", chdir = T)
Exploit the implicit "--file" argument of Rscript
When calling the script using "Rscript" (Rscript doc) the full path of the script is given as a system parameter. The following function exploits this to extract the script directory:
getScriptPath <- function(){
cmd.args <- commandArgs()
m <- regexpr("(?<=^--file=).+", cmd.args, perl=TRUE)
script.dir <- dirname(regmatches(cmd.args, m))
if(length(script.dir) == 0) stop("can't determine script dir: please call the script with Rscript")
if(length(script.dir) > 1) stop("can't determine script dir: more than one '--file' argument detected")
return(script.dir)
}
If you wrap your code in a package, you can always query parts of the package directory.
Here is an example from the RGtk2 package:
> system.file("ui", "demo.ui", package="RGtk2")
[1] "C:/opt/R/library/RGtk2/ui/demo.ui"
>
You can do the same with a directory inst/glade/ in your sources which will become a directory glade/ in the installed package -- and system.file() will compute the path for you when installed, irrespective of the OS.
This answer works fine to me:
script.dir <- dirname(sys.frame(1)$ofile)
Note: script must be sourced in order to return correct path
I found it in: https://support.rstudio.com/hc/communities/public/questions/200895567-can-user-obtain-the-path-of-current-Project-s-directory-
But I still don´t understand what is sys.frame(1)$ofile. I didn´t find anything about that in R Documentation. Someone can explain it?
#' current script dir
#' #param
#' #return
#' #examples
#' works with source() or in RStudio Run selection
#' #export
z.csd <- function() {
# http://stackoverflow.com/questions/1815606/rscript-determine-path-of-the-executing-script
# must work with source()
if (!is.null(res <- .thisfile_source())) res
else if (!is.null(res <- .thisfile_rscript())) dirname(res)
# http://stackoverflow.com/a/35842176/2292993
# RStudio only, can work without source()
else dirname(rstudioapi::getActiveDocumentContext()$path)
}
# Helper functions
.thisfile_source <- function() {
for (i in -(1:sys.nframe())) {
if (identical(sys.function(i), base::source))
return (normalizePath(sys.frame(i)$ofile))
}
NULL
}
.thisfile_rscript <- function() {
cmdArgs <- commandArgs(trailingOnly = FALSE)
cmdArgsTrailing <- commandArgs(trailingOnly = TRUE)
cmdArgs <- cmdArgs[seq.int(from=1, length.out=length(cmdArgs) - length(cmdArgsTrailing))]
res <- gsub("^(?:--file=(.*)|.*)$", "\\1", cmdArgs)
# If multiple --file arguments are given, R uses the last one
res <- tail(res[res != ""], 1)
if (length(res) > 0)
return (res)
NULL
}
A lot of these solutions are several years old. While some may still work, there are good reasons against utilizing each of them (see linked source below). I have the best solution (also from source): use the here library.
Original example code:
library(ggplot2)
setwd("/Users/jenny/cuddly_broccoli/verbose_funicular/foofy/data")
df <- read.delim("raw_foofy_data.csv")
Revised code
library(ggplot2)
library(here)
df <- read.delim(here("data", "raw_foofy_data.csv"))
This solution is the most dynamic and robust because it works regardless of whether you are using the command line, RStudio, calling from an R script, etc. It is also extremely simple to use and is succinct.
Source: https://www.tidyverse.org/articles/2017/12/workflow-vs-script/
I have found something that works for me.
setwd(dirname(rstudioapi::getActiveDocumentContext()$path))
How about using system and shell commands? With the windows one, I think when you open the script in RStudio it sets the current shell directory to the directory of the script. You might have to add cd C:\ e.g or whatever drive you want to search (e.g. shell('dir C:\\*file_name /s', intern = TRUE) - \\ to escape escape character). Will only work for uniquely named files unless you further specify subdirectories (for Linux I started searching from /). In any case, if you know how to find something in the shell, this provides a layout to find it within R and return the directory. Should work whether you are sourcing or running the script but I haven't fully explored the potential bugs.
#Get operating system
OS<-Sys.info()
win<-length(grep("Windows",OS))
lin<-length(grep("Linux",OS))
#Find path of data directory
#Linux Bash Commands
if(lin==1){
file_path<-system("find / -name 'file_name'", intern = TRUE)
data_directory<-gsub('/file_name',"",file_path)
}
#Windows Command Prompt Commands
if(win==1){
file_path<-shell('dir file_name /s', intern = TRUE)
file_path<-file_path[4]
file_path<-gsub(" Directory of ","",file_path)
filepath<-gsub("\\\\","/",file_path)
data_directory<-file_path
}
#Change working directory to location of data and sources
setwd(data_directory)
Thank you for the function, though I had to adjust it a Little as following for me (W10):
#Windows Command Prompt Commands
if(win==1){
file_path<-shell('dir file_name', intern = TRUE)
file_path<-file_path[4]
file_path<-gsub(" Verzeichnis von ","",file_path)
file_path<-chartr("\\","/",file_path)
data_directory<-file_path
}
In my case, I needed a way to copy the executing file to back up the original script together with its outputs. This is relatively important in research. What worked for me while running my script on the command line, was a mixure of other solutions presented here, that looks like this:
library(scriptName)
file_dir <- gsub("\\", "/", fileSnapshot()$path, fixed=TRUE)
file.copy(from = file.path(file_dir, scriptName::current_filename()) ,
to = file.path(new_dir, scriptName::current_filename()))
Alternatively, one can add to the file name the date and our to help in distinguishing that file from the source like this:
file.copy(from = file.path(current_dir, current_filename()) ,
to = file.path(new_dir, subDir, paste0(current_filename(),"_", Sys.time(), ".R")))
None of the solutions given so far work in all circumstances. Worse, many solutions use setwd, and thus break code that expects the working directory to be, well, the working directory — i.e. the code that the user of the code chose (I realise that the question asks about setwd() but this doesn’t change the fact that this is generally a bad idea).
R simply has no built-in way to determine the path of the currently running piece of code.
A clean solution requires a systematic way of managing non-package code. That’s what ‘box’ does. With ‘box’, the directory relative to the currently executing code can be found trivially:
box::file()
However, that isn’t the purpose of ‘box’; it’s just a side-effect of what it actually does: it implements a proper, modern module system for R. This includes organising code in (nested) modules, and hence the ability to load code from modules relative to the currently running code.
To load code with ‘box’ you wouldn’t use e.g. source(file.path(box::file(), 'foo.r')). Instead, you’d use
box::use(./foo)
However, box::file() is still useful for locating data (i.e. OP’s use-case). So, for instance, to locate a file mygui.glade from the current module’s path, you would write.
glade_path = box::file('mygui.glade')
And (as long as you’re using ‘box’ modules) this always works, doesn’t require any hacks, and doesn’t use setwd.

Resources