# Wrapping a simple R package

**URL:** <https://discourse.julialang.org/t/wrapping-a-simple-r-package/55349>\
**Category:** Machine Learning\
**Tags:** interoperability, linear-interaction, rcall\
**Created:** [February 15, 2021, 8:50pm UTC](https://discourse.julialang.org/t/wrapping-a-simple-r-package/55349 "2021-02-15T20:50:31Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)\
**Post date:** [February 15, 2021, 8:50pm UTC](https://discourse.julialang.org/t/wrapping-a-simple-r-package/55349/1 "2021-02-15T20:50:32Z")

</div>

I want to wrap a simple ML package: [sprintr](https://cran.r-project.org/web/packages/sprintr/index.html).  
In R the code is straight-forward:

```nohighlight
library(sprintr); 
m = cv.sprinter(x = X, y = y)
pred = predict(m, newdata = XH)

```

In Julia it works in 1-step:

```julia
X = randn(100,5)
y = 7.0 .+ X[:,1] .+ 2.0 .* X[:,2] .* X[:,3] + 3*randn(100)
using RCall

function sprintr(X, y, XH)
  @rput y X XH # put data from Julia to R.
  R"""
  library(sprintr); 
  m = cv.sprinter(x = X, y = y)
  pred = predict(m, newdata = XH)
  """
  return @rget pred  
end
sprintr(X, y, X) #1 step works fine

```

Now in 2-steps `fit()` and `predict()`:

```julia
function fitsprintr(X, y)
  @rput y X # put data from Julia to R.
  R"""
  library(sprintr); 
  m = cv.sprinter(x = X, y = y)
  """
  return @rget m  
end
function predictsprintr(m, XH)
  @rput m XH # put data from Julia to R.
  R"""
  library(sprintr); 
  pred = predict(m, newdata = XH)
  """
  return @rget pred  
end

```

It breaks in the 2nd step:

```julia
julia> ms = fitsprintr(X, y)
OrderedCollections.OrderedDict{Symbol,Any} with 12 entries:
  :n => 100
  :p => 5
  :a0 => 6.88335
  :compact => [0.0 1.0 0.981719; 0.0 2.0 0.801296; … ; 3.0 5.0 0.0285869; 2.0 3.0 1.46116]
  :fit => OrderedCollections.OrderedDict{Symbol,Any}(:n=>100,:p=>5,:a0=>[6.91957, 6.91288, 6.91104, 6.91314, 6.91492, 6.91654, 6.91801, 6.91434, 6.91025, 6.90653 … 7.21865, 7.21867, 7.21869, 7.21871, 7.21873, 7.21874, 7.…
  :fitted => [4.00406, 5.49018, 6.72736, 8.49206, 7.45682, 2.46833, 6.28563, 5.69402, 6.96177, 7.84651 … 6.00993, 7.37945, 7.11813, 7.2942, 5.92529, 8.71639, 7.63545, 5.86258, 7.62806, 6.30384]
  :lambda => [1.74206, 1.5873, 1.44629, 1.3178, 1.20073, 1.09406, 0.996869, 0.90831, 0.827618, 0.754095 … 0.000402438, 0.000366686, 0.000334111, 0.00030443, 0.000277385, 0.000252743, 0.00023029, 0.000209831, 0.000191191, 0.…
  :cvm => [3.90709, 3.86828, 3.81234, 3.7361, 3.64678, 3.55014, 3.46599, 3.39412, 3.33097, 3.28259 … 3.33651, 3.33662, 3.33672, 3.33682, 3.3369, 3.33698, 3.33705, 3.33711, 3.33717, 3.33722]
  :cvsd => [0.425856, 0.42167, 0.417286, 0.399112, 0.384055, 0.366016, 0.353135, 0.345567, 0.341965, 0.33731 … 0.627155, 0.627222, 0.627282, 0.627338, 0.627388, 0.627434, 0.627476, 0.627514, 0.627549, 0.62758]
  :foldid => [4, 4, 1, 3, 3, 1, 3, 5, 2, 3 … 3, 1, 2, 2, 1, 2, 1, 5, 2, 3]
  ⋮ => ⋮
julia> predictsprintr(ms, X)
ERROR: MethodError: no method matching sexpclass(::Expr)
Closest candidates are:
  sexpclass(::UInt8) at /Users/AZevelev/.julia/packages/RCall/eRsxl/src/convert/default.jl:236
  sexpclass(::Dates.Date) at /Users/AZevelev/.julia/packages/RCall/eRsxl/src/convert/default.jl:260
  sexpclass(::Dates.DateTime) at /Users/AZevelev/.julia/packages/RCall/eRsxl/src/convert/default.jl:265
  ...
Stacktrace:
 [1] sexp(::Expr) at /Users/AZevelev/.julia/packages/RCall/eRsxl/src/convert/default.jl:214
 [2] setindex!(::Ptr{VecSxp}, ::Expr, ::Int64) at /Users/AZevelev/.julia/packages/RCall/eRsxl/src/methods.jl:188
 [3] sexp(::Type{RCall.RClass{:list}}, ::OrderedCollections.OrderedDict{Symbol,Any}) at /Users/AZevelev/.julia/packages/RCall/eRsxl/src/convert/base.jl:281
 [4] sexp at /Users/AZevelev/.julia/packages/RCall/eRsxl/src/convert/default.jl:214 [inlined]
 [5] setindex!(::Ptr{VecSxp}, ::OrderedCollections.OrderedDict{Symbol,Any}, ::Int64) at /Users/AZevelev/.julia/packages/RCall/eRsxl/src/methods.jl:188
 [6] sexp(::Type{RCall.RClass{:list}}, ::OrderedCollections.OrderedDict{Symbol,Any}) at /Users/AZevelev/.julia/packages/RCall/eRsxl/src/convert/base.jl:281
 [7] sexp at /Users/AZevelev/.julia/packages/RCall/eRsxl/src/convert/default.jl:214 [inlined]
 [8] setindex!(::Ptr{EnvSxp}, ::OrderedCollections.OrderedDict{Symbol,Any}, ::Symbol) at /Users/AZevelev/.julia/packages/RCall/eRsxl/src/methods.jl:546
 [9] setindex! at /Users/AZevelev/.julia/packages/RCall/eRsxl/src/methods.jl:555 [inlined]
 [10] predictsprintr(::OrderedCollections.OrderedDict{Symbol,Any}, ::Array{Float64,2}) at ./REPL[34]:2
 [11] top-level scope at REPL[43]:1

```

I think the problem is putting m back into R from Julia.  
This is an issue for me bc to wrap an ML package I need separate functions for `fit` and `predict`

---

<div class="post-metadata">

**Author:** ![nignatiadis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nignatiadis/32/22035_2.png) [@nignatiadis](https://discourse.julialang.org/u/nignatiadis)\
**Post date:** [February 16, 2021, 3:41am UTC](https://discourse.julialang.org/t/wrapping-a-simple-r-package/55349/2 "2021-02-16T03:41:17Z")

</div>

Hi Alex,

I think something as follows should work:

```julia
function fitsprintr(X, y)
    @rput y X # put data from Julia to R.
    R"""
    library(sprintr);
     m <- cv.sprinter(x = X, y = y)
    """
    @rget m
    delete!(m, :call)
    delete!(m[:fit], :call)
    m
end

```

```julia
function predictsprintr(m, XH)
    @rput m XH # put data from Julia to R.
    R"""
    library(sprintr);
    class(m) <- 'cv.sprinter'
    pred <- predict(m, newdata = XH)
    """
    return @rget pred
end

```

I am not sure why RCall cannot convert `::Expr` from Julia to R (the first part takes care of this by removing all expressions). Furthermore, the R class information is lost when the R object is converted to a Julia object (the second function handles this). A more elegant solution could use RCall’s custom conversions ([Custom Conversion · RCall.jl](https://juliainterop.github.io/RCall.jl/dev/custom/)).

---

<div class="post-metadata">

**Author:** ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)\
**Post date:** [February 16, 2021, 4:47am UTC](https://discourse.julialang.org/t/wrapping-a-simple-r-package/55349/3 "2021-02-16T04:47:37Z")

</div>

@nignatiadis

1. welcome to Discourse, it’s great to have you here
2. it works well. Thank you!!!
3. it’s strange this is so awkward to do in RCall.jl

Now I can slowly start wrapping my fav R packages into Julia!
