RCall.jl
RCall.jl copied to clipboard
Unable to convert Julia Array{Tuple,1} to R object with @rput
When I try to convert an Array{Tuple,1} using @rput I get the following error:
ERROR: MethodError: no method matching sexp(::Tuple{Int64,Int64})
Is this a bug or intended functionality. How can I convert this julia object into R?
There is no tuple correspondence defined now. You will need to convert each tuple into an array first.
we could convert tuples to an R list?
There is one problem in converting tuples to plain R lists because plain R lists get converted to Array{Any} in Julia, so converting back and forth will change the type of Julia variable.
The way to handle this in JuliaCall is to convert tuples into R list with S3 class JuliaTuple.
Before loading the R library JuliaCall:
julia> using RCall
julia> RObject((2,3))
ERROR: MethodError: no method matching sexpclass(::Tuple{Int64,Int64})
Closest candidates are:
sexpclass(::Nothing) at /Users/lichangcheng/.julia/packages/RCall/RPlFw/src/convert/default.jl:218
sexpclass(::Missing) at /Users/lichangcheng/.julia/packages/RCall/RPlFw/src/convert/default.jl:219
sexpclass(::Symbol) at /Users/lichangcheng/.julia/packages/RCall/RPlFw/src/convert/default.jl:222
...
Stacktrace:
[1] sexp(::Tuple{Int64,Int64}) at /Users/lichangcheng/.julia/packages/RCall/RPlFw/src/convert/default.jl:214
[2] RObject(::Tuple{Int64,Int64}) at /Users/lichangcheng/.julia/packages/RCall/RPlFw/src/convert/default.jl:209
[3] top-level scope at none:0
Loading JuliaCall:
julia> R"library(JuliaCall)"
RObject{StrSxp}
[1] "JuliaCall" "stats" "graphics" "grDevices" "utils" "datasets"
[7] "methods" "base"
julia> R"julia_setup()"
┌ Warning: RCall.jl: Julia version 1.0.2 at location /Applications/Julia-1.0.app/Contents/Resources/julia/bin will be used.
│ Loading setup script for JuliaCall...
└ @ RCall ~/.julia/packages/RCall/RPlFw/src/io.jl:110
┌ Warning: RCall.jl: Finish loading setup script for JuliaCall.
└ @ RCall ~/.julia/packages/RCall/RPlFw/src/io.jl:110
RObject{EnvSxp}
<environment: 0x7fc87d6f72e0>
After loading JuliaCall:
julia> RObject((2,3))
RObject{VecSxp}
[[1]]
[1] 2
[[2]]
[1] 3
attr(,"class")
[1] "JuliaTuple"
And Julia objects with types like Array{Tuple, 1} are also handled like this:
julia> RObject([(1,2), (3,4)])
RObject{EnvSxp}
Julia Object of type Array{Tuple{Int64,Int64},1}.
Tuple{Int64,Int64}[(1, 2), (3, 4)]
Basic operations on the converted object are also possible in R:
julia> a = [(1,2), (3,4)]
2-element Array{Tuple{Int64,Int64},1}:
(1, 2)
(3, 4)
julia> @rput a
2-element Array{Tuple{Int64,Int64},1}:
(1, 2)
(3, 4)
julia> R"a[1]"
RObject{VecSxp}
[[1]]
[1] 1
[[2]]
[1] 2
attr(,"class")
[1] "JuliaTuple"
julia> R"a[1][1]"
RObject{VecSxp}
[[1]]
[1] 1
julia> R"a[1][[1]]"
RObject{IntSxp}
[1] 1
Lots of things don't round trip, so that isn't exactly a requirement.
I do like the idea of using S3 classes, but would need some testing.
Yes, I think it is only a desirable feature, especially considering tuples are quite common in Julia, it is helpful to have an R class converting to tuples in Julia and to have tuples in Julia converting to it.
FYI, reticulate converts R list to python tuple and vice versa.
Do we want to follow their standard https://rstudio.github.io/reticulate/#type-conversions
Until this is developed @Non-Contradiction, I will follow @randy3k's suggestion. Because I'd like to convert a large set of tuples to R objects, I'll split the tuples into two vectors, convert to R objects, and convert to tuples within R instead. Thanks for looking into this!