JuliaInterop / JuliaCall

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

pass paramter to Julia as Symbol #104

Closed ccshao closed 5 years ago

ccshao commented 5 years ago

I was trying to run NMF.jl from R, and was confused how to pass the variable to alg as Symbol required by the julia function nnmf.

nnmf stats:

alg: A symbol that indicates the factorization algorithm (default = :alspgrad).

In julia, an example codes will be r = nnmf(X, k; alg = :multmse, init = :nndsvd)

In R, I have tried

res <- julia_call("NMF.nnmf", mat, as.integer(k), init = nndsvd, need_return = "R")
res <- julia_call("NMF.nnmf", mat, as.integer(k), init = :nndsvd, need_return = "R")
res <- julia_call("NMF.nnmf", mat, as.integer(k), init = ":nndsvd", need_return = "R")
res <- julia_call("NMF.nnmf", mat, as.integer(k), init = "nndsvd", need_return = "R")

Then it said type error in the last two examples.

TypeError: in keyword argument init, expected Symbol, got String

How to properly use the julia_call to pass the parameter value as Symbol?

Non-Contradiction commented 5 years ago

Thanks for the feedback! Generally, if you have no idea of how to pass R objects as Julia objects of certain types, you can get some idea using julia_eval to see what is the corresponding R type of the Julia type. For example, a not elegant general solution is

nndsvd <- julia_eval(":nndsvd") 
# or julia_eval(":nndsvd", need_return = "J") to coerce the preserving of the Julia type
res <- julia_call("NMF.nnmf", mat, as.integer(k), init = nndsvd, need_return = "R")

In this special case,

> julia_eval(":multmse")
multmse
> typeof(julia_eval(":multmse"))
[1] "symbol"
> typeof(quote(multmse))
[1] "symbol"
> julia_call("typeof", quote(multmse))
Julia Object of type DataType.
Symbol

So the corresponding for a Julia Symbol is an R symbol, which can be obtained by quote(xxx).

I think I can add some examples like this in README or vignettes.

ccshao commented 5 years ago

Thanks for the quick help!

Both

nndsvd <- julia_eval(":nndsvd") 
julia_call("NMF.nnmf", mat, as.integer(k), init = nndsvd)

and res <- julia_call("NMF.nnmf", mat, as.integer(k), init = quote(nndsvdar)) works