R.matlab cannot set matlab function - r

I was trying to reproduce the setfunction example in R.matlab. My code is
library(R.matlab)
Matlab$startServer()
matlab <- Matlab()
isOpen <- open(matlab)
setFunction(matlab, " \
function [win, aver] = dice(B) \
%Play the dice game B times \
gains = [-1, 2, -3, 4, -5, 6]; \
plays = unidrnd(6, B, 1); \
win = sum(gains(plays)); \
aver = win/B; \
")
I encountered the error:
I also tried adding an end at the end of the matlab function, but still had the same error.
How can I avoid the error and set the matlab function within R?

Related

Using blas/Lapack in Fortran file for R

I have the following problem. I have a file say file.f90 in which I have implemented some Fortran subroutines, say called foo. Then I compile these functions using "R CMD SHLIB file.f90". To use the function foo in a seperate R file I then use dyn.load("foo.dll") and to call it .Fortran("foo", ...).
So far so good. But now I need to use some functions implemented in Lapack.
I have no idea how to do this or where to have a look. I have only tried calling "R CMD SHLIB file.f90 -llapack" but already there I get an error that llapack has not been found. Any hints would be greatly appreciated!!
EDIT:
I have finally found an answer to my question with the help of everyone here and with looking up much on the internet. I have to say the solution is quite easy but as I am quite a noob when it comes to these things it still took some time. So here s my solution for Windows 11 and R studio 4.1
Assume that our R session/project has the path PATH_PROJ, e.g "C:\Users\Myname\Documents\MyProject". Then I created a new folder named "f90files" in which I intended to save all Fortran functions, so PATH_PROJ\f90files.
Next, I needed the path of my R's Lapack PATH_LAPACK, e.g "C:\Program Files\R\R-4.1.2\bin\x64\Rlapack.dll".
In PATH_PROJ\f90files I then implemented the Fortran subroutine as suggested by Jean-Claude Arbaut:
subroutine eigvals(n, a, vre, vim, info)
implicit none
integer :: n, info
integer, parameter :: lwork = 65536
double precision :: a(n, n), vre(n), vim(n)
double precision, save :: work(lwork)
call dgeev("n", "n", n, a, n, vre, vim, 0d0, 1, 0d0, 1, work, lwork, info)
end subroutine
Following this, I started up Windows command prompt and typed
gfortran -shared PATH_LAPACK PATH_PROJ\f90files\eigvals.f90 -o PATH_PROJ\f90files\eigvals.so -o PATH_PROJ\f90files\eigvals.dll
and further
gfortran -shared PATH_LAPACK PATH_PROJ\f90files\eigvals.f90 -o PATH_PROJ\f90files\eigvals.so
(maybe this can be done in one go?)
With this all was nicely compiled. In R I then loaded the function using
dyn.load("PATH_PROJ\f90files\eigvals.dll")
Finally, using the implementation given below, I ran
eigvals <- function(a) {
if (is.matrix(a) && is.double(a) && nrow(a) == ncol(a)) {
n <- nrow(a)
s <- .Fortran("eigvals", n = as.integer(n), a = a, vre = double(n), vim = double(n), info = 0L)
structure(complex(real = s$vre, imaginary = s$vim), info = s$info)
} else stop("Invalid input")
}
eigvals(a)
and voilĂ  we are done! Thanks again to everyone!
The libraries you are looking for are Rblas.dll and Rlapack.dll in the R-4.2.2\bin\x64 directory (replace 4.2.2 with your version).
Here is an example. Let's compute eigenvalues using LAPACK's dgeev.
Fortran file eigvals.f90. Here to simplify lwork is a constant, but in "real" code you would have to do this more carefully.
subroutine eigvals(n, a, vre, vim, info)
implicit none
integer :: n, info
integer, parameter :: lwork = 65536
double precision :: a(n, n), vre(n), vim(n)
double precision, save :: work(lwork)
call dgeev("n", "n", n, a, n, vre, vim, 0d0, 1, 0d0, 1, work, lwork, info)
end subroutine
Compile with either one of the following commands (change the path as necessary). If you are on Windows, do this from the Rtools bash window. On Linux the extension is .so and not .dll.
gfortran -shared -L/c/App/R/R-4.2.2/bin/x64 eigvals.f90 -lRlapack -o eigvals.dll
R CMD SHLIB eigvals.f90 -lRlapack
In R, you can now do, assuming you have setwd() to the directory containing the DLL:
a <- matrix(c(2, 9, 4, 7, 5, 3, 6, 1, 8), 3, 3, byrow = T)
dyn.load("eigvals.dll")
is.loaded("eigvals")
eigvals <- function(a) {
if (is.matrix(a) && is.double(a) && nrow(a) == ncol(a)) {
n <- nrow(a)
s <- .Fortran("eigvals", n = as.integer(n), a = a, vre = double(n), vim = double(n), info = 0L)
structure(complex(real = s$vre, imaginary = s$vim), info = s$info)
} else stop("Invalid input")
}
eigvals(a)
Pay attention to the number and type of subroutine arguments in .Fortran, otherwise you may crash R. Note also that you must call Fortran subroutines, not functions.
I you are on Windows and using R-4.2 with Rtools 4.2, there is an extra trick: the compiler is no longer in the default directories. See this. You have first to do, in the Rtools bash window:
export PATH=/x86_64-w64-mingw32.static.posix/bin:$PATH
If you are using the compiler from the Windows command prompt, you will have to modify the PATH environment variable accordingly.

R plotting has issues with producing text/number labels

I am having issues with my general R plotting functions. From a fresh R restart, and without loading any packages, I run this:
png(file ="mtcars.png", width = 1600, height = 1600, units = "px", res = 300)
hist(mtcars$mpg, breaks = 'FD', col = 'blue', xlab = 'MPG', main = 'MPG of mtcars Dataset')
dev.off()
And the result is what you see in this post. There's some weird squares where the labels should be. I am running R in a new docker image and have no idea what I forgot to install. Somebody help!
My dockerfile contains:
RUN conda install -y r-base && conda install -c bioconda -y r-devtools
RUN \
/opt/conda/lib/R/bin/R -e "getOption(\"unzip\") ; options(repos = list(CRAN=\"http://cran.rstudio.com/\")) ; Sys.getenv(\"TAR\") ; options(unzip = \"/opt/conda/bin/unzip\") ; \
Sys.setenv(TAR = \"/bin/tar\"); library(devtools) ; install.packages(c('Seurat','XML','ggplot2')) ; \
devtools::install_github(repo = 'satijalab/seurat-wrappers',quiet=T) ; \
if (!requireNamespace(\"BiocManager\", quietly = TRUE)) { \
install.packages(c(\"BiocManager\"), quiet = T) \
} ; \
BiocManager::install('monocle') ; devtools::install_github('hms-dbmi/conos')"

R stan 8schools example faile

I am trying to run classical r-stan example from this official tutorial. But I can't because I get the following error message:
The code I use is as follows:
schools_dat <- list(J = 8,
y = c(28, 8, -3, 7, -1, 1, 18, 12),
sigma = c(15, 10, 16, 11, 9, 11, 10, 18))
fit <- stan(file = '8schools.stan', data = schools_dat,
iter = 1000, chains = 4)
Where 8schools.stan is file I have additionally created and nested with the following code:
data {
int<lower=0> J; // number of schools
real y[J]; // estimated treatment effects
real<lower=0> sigma[J]; // s.e. of effect estimates
}
parameters {
real mu;
real<lower=0> tau;
real eta[J];
}
transformed parameters {
real theta[J];
for (j in 1:J)
theta[j] = mu + tau * eta[j];
}
model {
target += normal_lpdf(eta | 0, 1);
target += normal_lpdf(y | theta, sigma);
}
I want to figure out the reasons of this error and how to avoid it.
Additionally I want mention that:
The following code works propertly and returns 10:
fx <- inline::cxxfunction( signature(x = "integer", y = "numeric" ) , '
return ScalarReal( INTEGER(x)[0] * REAL(y)[0] ) ;
' )
fx( 2L, 5 )
I have installed latest frozen version of Rtools.
Also, Rtools, R and Rstudio are located in folders without spaces.
I work on Windows (not laptop)
I have been strictly following all the steps from installiation guide.
Will be very greatfull for help!
Update
I also have set Sys.setenv(USE_CXX14=1) as Ben Goodrich has suggested but now I get the following error message
This is a temporary issue due to the fact that (this week) the StanHeaders R package (which requires C++14) has been accepted on CRAN but not yet the rstan R package (which uses C++14 to compile the models). So, for the time being, you first need to call
Sys.setenv(USE_CXX14=1)
But anyone reading this post much in the future is unlikely to need to do that explicitly (the rstan R package will do it internally).
On Windows you need to put
CXX14=g++ -std=c++1y
CXX14FLAGS=-O3
into the ~/.R/Makevars file but on a Mac, those lines should already be there.

building a nested pyparsing.Dict from a nested list

My input is growing from simple 2-level nested lists to a complex nested list of lists. I see where pyparsing.nestedExpr() is the bees' knees for this kind of thing, but I'm still wanting to build up a nested Dict structure.
With the basics somewhat squared away I've crafted this:
import pyparsing as pp
input_works = '''
(unitsOfMeasure
(altitudeUnits "m")
(capacitanceUnits "pF")
(designUnits "MIL")
(drawingUnits "MIL")
(drawingAccuracy 2)
(drawingHeight 28000)
)''
# recursive dict
input_doesnt_work = '''
(parameterFile "out.tf"
(revision "15.6")
(xcoord 1234.567)
(ycoord -3456.890)
(unitsOfMeasure
(altitudeUnits "m")
(capacitanceUnits "pF")
(designUnits "MIL")
(drawingUnits "MIL")
(drawingAccuracy 2)
(drawingHeight 28000)
)
)'''
v_string = pp.Word(pp.alphanums+'_'+'-'+'.')
v_quoted_string = pp.Combine( '"' + v_string + '"')
v_number = pp.Regex(r'[+-]?(?P<float1>\d+)(?P<float2>\.\d+)?(?P<float3>[Ee][+-]?\d+)?')
keyy = v_string
valu = pp.Or( [ v_string, v_quoted_string, v_number])
item = pp.Group( pp.Literal('(').suppress() + keyy + pp.OneOrMore( valu) + pp.Literal(')').suppress() )
# some magic - use Forward to make the dicts self-referential and thus recursive
dicts = pp.Forward()
dicts << pp.Group( pp.Literal('(').suppress() + \
keyy + \
pp.Optional( valu) + \
pp.OneOrMore( pp.Or( item, dicts)) + \
pp.Literal(')').suppress() )
print "dicts_input_works yields: ", dicts.parseString( input_works)
print "dicts_input_doesnt_work yields: ", dicts.parseString( input_doesnt_work
input_doesnt_work chokes on like 6, col 5, as if the self-reference in
pp.OneOrMore( pp.Or( item, dicts))
isn't being seen.
TIA,
code_warrior
Spotted my error 3sec after posting:
pp.OneOrMore( pp.Or( item, dicts )) + \ # wrong
pp.OneOrMore( pp.Or( [item, dicts] )) + \ # right
Never mind, nothing to see here, move along.
Thanks,
code_warrior

How to evaluate this scheme in RWeka?

The scheme I am trying to evaluate is:
weka.classifiers.meta.AttributeSelectedClassifier -E "weka.attributeSelection.CfsSubsetEval " -S "weka.attributeSelection.BestFirst -D 1 -N 5" -W weka.classifiers.functions.SMOreg -- -C 1.0 -N 0 -I "weka.classifiers.functions.supportVector.RegSMOImproved -L 0.0010 -W 1 -P 1.0E-12 -T 0.0010 -V" -K "weka.classifiers.functions.supportVector.PolyKernel -C 250007 -E 1.0"
i.e. I am trying to run an AttributeSelectedClassifier with an SMOreg classifier inside. Every other parameter is the default value of the respective classifier.
So the R code is:
optns <- Weka_control(W = "weka.classifiers.functions.SMOreg")
ASC <- make_Weka_classifier("weka/classifiers/meta/AttributeSelectedClassifier")
model <- ASC(class ~ ., data = as.data.frame(dat), control = optns)
evaluation <- evaluate_Weka_classifier(model, numFolds = 10)
evaluation
When I run the above R code I get this error:
Error in .jcall(evaluation, "D", x, ...) : java.lang.NullPointerException
The above error happens in RWeka's evaluate.R where it tries to call the WEKA methods: "pctCorrect", "pctIncorrect", "pctUnclassified", "kappa", "meanAbsoluteError","rootMeanSquaredError","relativeAbsoluteError","rootRelativeSquaredError"
I also tried manually specifying the default values using the Weka_control object like so:
optns <- Weka_control(E = "weka.attributeSelection.CfsSubsetEval ",
S = list("weka.attributeSelection.BestFirst", D = 1,N = 5),
W = list("weka.classifiers.functions.SMOreg", "--",
C=1.0, N=0,
I = list("weka.classifiers.functions.supportVector.RegSMOImproved",
L = 0.0010, W=1,P=1.0E-12,T=0.0010,V=TRUE),
K = list("weka.classifiers.functions.supportVector.PolyKernel",
C=250007, E=1.0)))
ASC <- make_Weka_classifier("weka/classifiers/meta/AttributeSelectedClassifier")
model <- ASC(class ~ ., data = as.data.frame(dat), control = optns)
evaluation <- evaluate_Weka_classifier(model, numFolds = 10)
evaluation
and I get this error:
Error in .jcall(classifier, "V", "buildClassifier", instances) :
java.lang.Exception: Can't find class called: weka.classifiers.functions.SMOreg -- -C 1 -N 0 -I weka.classifiers.functions.supportVector.RegSMOImproved -L 0.001 -W 1 -P 1e-12 -T 0.001 -V -K weka.classifiers.functions.supportVector.PolyKernel -C 250007 -E 1
I tried your example but got a different error (where dat is my own data frame)
Error in model.frame.default(formula = class ~ ., data = dat) :
object is not a matrix
Your error may be not directly related to syntax of calling this Weka function but some issues with path setup.

Resources