Passing Formulas from R to Julia using XRJulia for Model Estimation

Passing Formulas from R to Julia via XRJulia

XRJulia is a package in R that allows you to use Julia code from within R, providing a seamless integration between the two languages. One of its key features is the ability to pass formulas from R to Julia for model estimation. In this article, we will delve into the details of how to achieve this and explore the challenges and potential solutions involved.

Background

XRJulia uses a combination of juliaEval, JuliaFunction, and juliaSend functions to communicate between R and Julia. The juliaEval function allows you to execute a string of Julia code within an R environment, while JuliaFunction wraps a Julia function in a way that can be called from R. juliaSend is used to send data from R to Julia.

Formulas in R

In R, formulas are created using the ~ operator and are typically used with functions such as lm() or glm(). The formula is used to specify the relationship between the dependent variable and one or more predictor variables. For example:

f <- ~ 1 + (1|learnid)

This formula specifies a linear model where the intercept is fixed, and the effect of learnid is modeled as a random effect.

Converting Formulas to Julia

To pass formulas from R to Julia, you need to convert them into something that can be used in Julia. In this case, we are using the juliaEval function to execute a string of Julia code that contains a formula. The formula is defined in Julia using the statsmodels.formula.api.formula() function.

Challenges

The problem arises when trying to pass R data frames directly from R to Julia using juliaSend. Currently, XRJulia does not support converting R data frames into Julia data frames.

One possible solution is to read the data frame into a Julia data frame or DataFrame. We can use the DataFrames package in Julia to create a data frame that can be used by the MixedModels package.

Solution 1: Reading Data Frames into Julia

We can use the juliaSend function to send individual columns from the R data frame to Julia, and then convert them back into integers if necessary. We can also combine these columns to create a new data frame in Julia using the DataFrames package.

library(XRJulia)
library(DataFrames)

findJulia(test = T) # Works fine

juliaEval("using MixedModels")

jlmerj <- juliaEval("
                      function(f,d)
                      m=fit(LinearMixedModel,f,d)
                      return(m)
                      end
                      ")

jlmer <- JuliaFunction(jlmerj)

mindata <- data.frame(IRI_EC = c(15, 14, 27, 0, 22, 16, 23, 17, 20, 26), learnid = factor(1:10))

jfrm <- juliaEval("@formula(IRI_EC ~  1 + (1|learnid))")

jIRI_EC <- juliaSend(mindata$IRI_EC)
## first convert factors to integers and convert back in julia
jlearnid <- juliaCall("CategoricalArrays.CategoricalArray", juliaSend(as.integer(mindata$learnid)))

## combine columns to create dataframe in julia
jdata <- juliaEval(paste0('DataFrame(Dict([(:IRI_EC,', juliaName(jIRI_EC),
                                    '), (:learnid, ', juliaName(jlearnid), ')]))'))

res <- jlmer(jfrm,jdata)

res

This code reads the mindata data frame into Julia and combines its columns to create a new data frame. It then uses this data frame to estimate the linear mixed effects model defined by the formula f.

Solution 2: Converting Dicts in julmerj

Another possible solution is to convert the R data frame directly into a dict (a dictionary-like data structure) within the jlmerj function. This can be done using the juliaCall function, which allows you to call Julia code from R.

library(XRJulia)

findJulia(test = T) # Works fine

juliaEval("using MixedModels")

jlmerj <- juliaEval("
                      function(f,d)
                      dict <- Dict([(:IRI_EC, d$IRI_EC), (:learnid, d$learnid)])
                      return(dict)
                      end
                      ")

mindata <- data.frame(IRI_EC = c(15, 14, 27, 0, 22, 16, 23, 17, 20, 26), learnid = factor(1:10))

jfrm <- juliaEval("@formula(IRI_EC ~  1 + (1|learnid))")

dict <- jlmerj(jfrm,mindata)

res <- mixedmodels::fit(lmer(f ~ (1|learnid), data=dict))

res

This code converts the mindata data frame directly into a dict within the jlmerj function. It then uses this dict to estimate the linear mixed effects model defined by the formula f.

In conclusion, passing formulas from R to Julia via XRJulia requires some creative workarounds due to the limitations of currently available packages and functions. However, with a little bit of effort, it is possible to achieve seamless integration between R and Julia for model estimation.


Last modified on 2023-11-11