Problem with RCall's @rget


#1

I am using RCall (julia 0.6) with R 3.3.3. Specifically, the R package “bnlearn”.
There seems to be some problem with importing a particular type of list structure from R:

> using RCall
> R"library(bnlearn)"
> R"data(marks)"
> R"bn = gs(marks)"
> bn = @rget bn
ERROR: MethodError: RCall.rcopy(::Type{Any}, ::Ptr{RCall.NilSxp}) is ambiguous. Candidates:
  rcopy(::Type{T}, ::Ptr{RCall.NilSxp}) where T in RCall at /usr/home/ko/.julia/v0.6/RCall/src/convert/base.jl:34
  rcopy(::Type{Any}, s::Ptr{S}) where S<:RCall.Sxp in RCall at /usr/home/ko/.julia/v0.6/RCall/src/convert/base.jl:31
Possible fix, define
  rcopy(::Type{Any}, ::Ptr{RCall.NilSxp})
Stacktrace:
 [1] rcopy(::Type{Dict{Symbol,Any}}, ::Ptr{RCall.VecSxp}) at /usr/home/ko/.julia/v0.6/RCall/src/convert/base.jl:151
 [2] #rcopy#70(::Array{Any,1}, ::Function, ::Ptr{RCall.VecSxp}) at /usr/home/ko/.julia/v0.6/RCall/src/convert/default.jl:15
 [3] rcopy(::Type{Any}, ::Ptr{RCall.VecSxp}) at /usr/home/ko/.julia/v0.6/RCall/src/convert/base.jl:31
 [4] rcopy(::Type{Dict{Symbol,Any}}, ::Ptr{RCall.VecSxp}) at /usr/home/ko/.julia/v0.6/RCall/src/convert/base.jl:151
 [5] #rcopy#70(::Array{Any,1}, ::Function, ::Ptr{RCall.VecSxp}) at /usr/home/ko/.julia/v0.6/RCall/src/convert/default.jl:15
 [6] #rcopy#69(::Array{Any,1}, ::Function, ::RCall.RObject{RCall.VecSxp}) at /usr/home/ko/.julia/v0.6/RCall/src/convert/default.jl:6
 [7] rcopy(::RCall.RObject{RCall.VecSxp}) at /usr/home/ko/.julia/v0.6/RCall/src/convert/default.jl:6

julia> 

"


#2

Apparently it is hitting an R NULL in an unexpected place.

You probably want to start with R’s str function to see the structure of the R object

julia> R"str(bn)"
List of 3
 $ learning:List of 7
  ..$ whitelist: NULL
  ..$ blacklist: NULL
  ..$ test     : chr "cor"
  ..$ args     :List of 1
  .. ..$ alpha: num 0.05
  ..$ ntests   : num 52
  ..$ algo     : chr "gs"
  ..$ optimized: logi FALSE
 $ nodes   :List of 5
  ..$ MECH:List of 4
  .. ..$ mb      : chr [1:2] "VECT" "ALG"
  .. ..$ nbr     : chr [1:2] "VECT" "ALG"
  .. ..$ parents : chr(0)
  .. ..$ children: chr(0)
  ..$ VECT:List of 4
  .. ..$ mb      : chr [1:2] "MECH" "ALG"
  .. ..$ nbr     : chr [1:2] "MECH" "ALG"
  .. ..$ parents : chr(0)
  .. ..$ children: chr(0)
  ..$ ALG :List of 4
  .. ..$ mb      : chr [1:4] "MECH" "VECT" "ANL" "STAT"
  .. ..$ nbr     : chr [1:4] "MECH" "VECT" "ANL" "STAT"
  .. ..$ parents : chr(0)
  .. ..$ children: chr(0)
  ..$ ANL :List of 4
  .. ..$ mb      : chr [1:2] "ALG" "STAT"
  .. ..$ nbr     : chr [1:2] "ALG" "STAT"
  .. ..$ parents : chr(0)
  .. ..$ children: chr(0)
  ..$ STAT:List of 4
  .. ..$ mb      : chr [1:2] "ALG" "ANL"
  .. ..$ nbr     : chr [1:2] "ALG" "ANL"
  .. ..$ parents : chr(0)
  .. ..$ children: chr(0)
 $ arcs    : chr [1:12, 1:2] "MECH" "MECH" "VECT" "VECT" ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "from" "to"
 - attr(*, "class")= chr "bn"
RCall.RObject{RCall.NilSxp}
NULL

The problem is in the learning component with its whitelist and blacklist components and the fact that they occur first

julia> rcopy(R"""bn$learning""")
ERROR: MethodError: RCall.rcopy(::Type{Any}, ::Ptr{RCall.NilSxp}) is ambiguous. Candidates:
  rcopy(::Type{T}, ::Ptr{RCall.NilSxp}) where T in RCall at /home/bates/.julia/v0.6/RCall/src/convert/base.jl:34
  rcopy(::Type{Any}, s::Ptr{S}) where S<:RCall.Sxp in RCall at /home/bates/.julia/v0.6/RCall/src/convert/base.jl:31
Possible fix, define
  rcopy(::Type{Any}, ::Ptr{RCall.NilSxp})
Stacktrace:
 [1] rcopy(::Type{Dict{Symbol,Any}}, ::Ptr{RCall.VecSxp}) at /home/bates/.julia/v0.6/RCall/src/convert/base.jl:151
 [2] #rcopy#70(::Array{Any,1}, ::Function, ::Ptr{RCall.VecSxp}) at /home/bates/.julia/v0.6/RCall/src/convert/default.jl:15
 [3] #rcopy#69(::Array{Any,1}, ::Function, ::RCall.RObject{RCall.VecSxp}) at /home/bates/.julia/v0.6/RCall/src/convert/default.jl:6
 [4] rcopy(::RCall.RObject{RCall.VecSxp}) at /home/bates/.julia/v0.6/RCall/src/convert/default.jl:6

The other components are okay, as you can check for yourself. So maybe the best course is to write the suggested rcopy method.

julia> RCall.rcopy(::Type{Any}, s::Ptr{RCall.NilSxp}) = nothing

julia> rcopy(R"bn")
Dict{Symbol,Any} with 3 entries:
  :nodes    => Dict{Symbol,Any}(Pair{Symbol,Any}(:ALG, Dict{Symbol,Any}(Pair{Symbol,Any}(:mb, String["M…
  :arcs     => String["MECH" "VECT"; "MECH" "ALG"; … ; "STAT" "ALG"; "STAT" "ANL"]
  :learning => Dict{Symbol,Any}(Pair{Symbol,Any}(:ntests, 52.0),Pair{Symbol,Any}(:blacklist, nothing),P…

#3

Thanks very much, that works. Is

|RCall.rcopy(::Type{Any}, s::Ptr{RCall.NilSxp}) = nothing|

of general utility, and so a candidate for inclusion in Rcall.jl?