JuliaInterop / JuliaCall

Embed Julia in R
https://non-contradiction.github.io/JuliaCall/index.html
Other
267 stars 36 forks source link

3D array from R to Julia #157

Closed ReneSkukies closed 3 years ago

ReneSkukies commented 3 years ago

Hey,

When I try to use the 3D array "data", of size 1 x 50 x 300, in a julia_call function I am getting a data conversion error (I think). The class of data is an array:

class(data)
"array"

dim(data)
[1]   1  50 300

However after conversion to Julia it results into a different type:

julia_call("typeof", data)
Julia Object of type DataType.
Base.ReshapedArray{Union{Missing, Float64},3,Array{Union{Missing, Float64},1},Tuple{}}

Do you know why this happens and maybe have a workaround for it? The desired datatype would be Array{T,3}, or rather Array{Union{Missing, Float64},3}

Non-Contradiction commented 3 years ago

Thank you very much for the feedback! I believe that the problem is related to the content and the generation procedure of data. Because array in R is a "ambiguous" data structure, and JuliaCall will use different conversion mechanisms for different situations. Could you provide some code to generate data, so we have a reproducible minimal working example for the issue?

The following simplest case works fine.

> library(JuliaCall)
> julia_setup()
Julia version 1.5.0 at location C:\Users\lch34\AppData\Local\JULIAC~1\JULIAC~1\julia\V15~1.0\bin will be used.
Loading setup script for JuliaCall...
Finish loading setup script for JuliaCall.
> data <- array(0, c(1,50,300))
> dim(data)
[1]   1  50 300
> class(data)
[1] "array"
> julia_call("typeof", data)
Julia Object of type DataType.
Array{Float64,3}

And the following will reproduce the "issue":

> data <- array(0,c(1,2,3))
> data[1,1,1]<-NA
> julia_call("typeof", data)
Julia Object of type DataType.
Base.ReshapedArray{Union{Missing, Float64},3,Array{Union{Missing, Float64},1},Tuple{}}

But I'm not sure whether the Base.ReshapedArray can be called a "type error". It is just a reshaped array in Julia, and it should support most array operation. For example, continue the second example, we have:

> julia_call("sqrt.", data)
, , 1

     [,1] [,2]
[1,]   NA    0

, , 2

     [,1] [,2]
[1,]    0    0

, , 3

     [,1] [,2]
[1,]    0    0

> 

And the Base.ReshapedArray is actually a "mimicking" of R data structure. Because in R, array is just a vector which has a dim property. Is there any reason why Array{T,3} is needed?

Non-Contradiction commented 3 years ago

I will think more about whether a plain Array{T,3} should be the conversion target. Any comments on pros and/or cons are welcome!

And the conversion to Array{T,3} can actually be achieved by

> julia_call("Array", data, need_return = "J")
Julia Object of type Array{Union{Missing, Float64},3}.
Union{Missing, Float64}[missing 0.0]

Union{Missing, Float64}[0.0 0.0]

Union{Missing, Float64}[0.0 0.0]
> Jdata <- julia_call("Array", data, need_return = "J")
> julia_call("typeof", Jdata)
Julia Object of type DataType.
Array{Union{Missing, Float64},3}
> julia_call("sqrt.", Jdata)
, , 1

     [,1] [,2]
[1,]   NA    0

, , 2

     [,1] [,2]
[1,]    0    0

, , 3

     [,1] [,2]
[1,]    0    0

>
ReneSkukies commented 3 years ago

Thank you for the answer! julia_call("Array", data, need_return = "J") solved the problem for my.

I am not sure Array{T,3} should be the target conversion either here, as I am working on a rather specific case involving EEG analysis workflow. The Array{T,3} structure is needed as each instance in the third dimension contains data around some event. So the structure is channel x time x epoch/ event.

Thanks again for the help!