Comments (9)
I don't think there's going to be an easy solution that will work for all functions which utilise non-standard evaluation. For plot
, I think it might be easier to create a macro that automatically generates labels:
macro rplot(x,y,args...)
:(rcall(:plot,$x,$y,xlab=$(string(x)),ylab=$(string(y)),$args...))
end
julia> macroexpand(:(@rplot(x,sin(x))))
:(rcall(:plot,x,sin(x),xlab="x",ylab="sin(x)",()...))
from rcall.jl.
There is also a related issue when doing lm
.
(PS: please checkout current master for DataFrame conversion)
using RCall
using RDatasets
mtcars = dataset("datasets", "mtcars");
rprint(rcall(:lm, "Disp~MPG", data=mtcars))
It returns
julia> rprint(rcall(:lm, "Disp~MPG", data=mtcars))
Call:
lm(formula = "Disp~MPG", data = structure(list(Model = c("Mazda RX4",
"Mazda RX4 Wag", "Datsun 710", "Hornet 4 Drive", "Hornet Sportabout",
"Valiant", "Duster 360", "Merc 240D", "Merc 230", "Merc 280",
.
.
.
4L, 4L, 4L, 4L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 3L, 3L, 3L,
3L, 3L, 4L, 5L, 5L, 5L, 5L, 5L, 4L), Carb = c(4L, 4L, 1L, 1L,
2L, 1L, 4L, 2L, 2L, 4L, 4L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 2L, 1L,
1L, 2L, 2L, 4L, 2L, 1L, 2L, 2L, 4L, 6L, 8L, 2L)), .Names = c("Model",
"MPG", "Cyl", "Disp", "HP", "DRat", "WT", "QSec", "VS", "AM",
"Gear", "Carb"), class = "data.frame", row.names = c(NA, 32L)))
Coefficients:
(Intercept) MPG
580.88 -17.43
from rcall.jl.
Eesh, that's messy.
from rcall.jl.
This may be a better way to resolve the lazy evaluation problem. It uses R_mkEVPROMISE
to create a promise object first.
using RCall
RCall.rgui_start()
macro promise(x)
sym = Expr(:quote, symbol(string(x)))
quote
RCall.preserve(sexp(ccall((:R_mkEVPROMISE,libR),Ptr{Void},(Ptr{Void},Ptr{Void}), sexp($sym), sexp($x))))
end
end
x = linspace(0,pi,10)
rcall(:plot, (@promise x), (@promise sin(x)))
EDIT:
This workaround can correctly handled substitute
but not match.call()
. Therefore, it doesn't solve the lm
issue.
reval("""
f <- function(x) substitute(x)
g <- function(x) match.call()
""");
rprint(rcall(:f, @promise x))
# x
rprint(rcall(:g, @promise x))
# g(x = c(0, 0.111111111111111, 0.222222222222222, 0.333333333333333,
# 0.444444444444444, 0.555555555555556, 0.666666666666667, 0.777777777777778,
# 0.888888888888889, 1))
from rcall.jl.
Nice! That's really cool.
Do you know what is the difference between R_mkEVPROMISE
and R_mkEVPROMISE_NR
?
from rcall.jl.
It is used to disabled reference counting so that gc()
will collect the corresponding memory. In default, R is using a different way to do reference counting. It is not relevant unless R is complied with SWITCH_TO_REFCNT
.
from rcall.jl.
I am trying an lazy
macro with the hope of handling non-standard evaluations. The idea is to copy the Julia objects to R in a sandbox environment. And then evaluate the function call in that environment.
macro lazy(expr)
blk = Expr(:block)
cleanup = Any[]
push!(blk.args,:(env = newEnvironment(rGlobalEnv)))
(expr.head == :call && expr.args[1] == :rcall) || error("expect rcall(f, args...)")
args = copy(expr.args)
shift!(args)
for (i,a) in enumerate(args)
if typeof(a) == Symbol
push!(blk.args,:(env[$(QuoteNode(a))] = sexp($(esc(a)))))
args[i] = QuoteNode(a)
push!(cleanup,:(env[$(QuoteNode(a))] = rNilValue))
elseif typeof(a) == Expr && a.head == :kw && typeof(a.args[2]) == Symbol
value = a.args[2]
push!(blk.args,:(env[$(QuoteNode(value))] = sexp($(esc(value)))))
args[i].args[2] = QuoteNode(value)
push!(cleanup,:(env[$(QuoteNode(value))] = rNilValue))
else
args[i] = :($(esc(a)))
end
end
ret_call = :(ret = reval(rlang_p(),env))
append!(ret_call.args[2].args[2].args, args)
push!(blk.args, ret_call)
append!(blk.args, cleanup)
push!(blk.args,:(ret))
blk
end
With this macro, I get this
julia> using RCall
julia> rmtcars = dataset("datasets", "mtcars");
julia> @lazy rcall(:lm, reval("as.formula('HP~MPG')"), data=rmtcars)
RCall.RObject{RCall.VecSxp}
Call:
lm(formula = HP ~ MPG, data = rmtcars)
Coefficients:
(Intercept) MPG
324.08 -8.83
from rcall.jl.
I think we should be able to do something like that inside the @R_str
macro.
My only question is if this breaks other functions which use this (e.g. update
)?
from rcall.jl.
I think the purposes of @R_str
and the @lazy
macro are little bit different.
@R_str
parses string to expressions. We need to evaluate expressions under the global environment to make sure that expressions like x <- 1
or a[3] <- 2
return expected results. If we create a sandbox environment to evaluate x<-1
, it only changes a local variable x
and the value the global variable x
is kept untouched.
On the other hand, @lazy
takes only function calls as input. It does not touch any R global variables, it means that @lazy
calls could be separated and sandboxed.
from rcall.jl.
Related Issues (20)
- why building RCall.jl failed during the registration of an package HOT 2
- RCall.jl failed to build with Conda (23.3.1) HOT 3
- "is.na() applied to non-(list or vector) of type 'language'" when passing a Julia's boolean variable to R's smooth.spline HOT 2
- Unable to Pkg.build RCall HOT 4
- Find the number of arguments for an RFunction? HOT 1
- loading RCall in atreplinit fails because of RPrompt HOT 1
- Error: attempt to apply non-function HOT 5
- [BUG] ArgumentError: malformed expression in formula HOT 3
- If julia functions which was brought to R throws an error, no real error is thrown, but an error object is returned #216 HOT 3
- Feature Request: Add possibility to build RCall without having R_HOME set HOT 3
- ERROR: UndefVarError: `val` not defined
- Segmentation fault on closing julia HOT 7
- equal `==` is not working on `reval` HOT 2
- Feature Request: Make RCall depend dynamically on `R_HOME` HOT 9
- Feature Request: show/display methods for R plots like ggplot2 HOT 3
- Could we add a point in the docs about setting up CI ? HOT 6
- ERROR: REvalError: Loading required package: mvtnorm HOT 1
- Difficulty installing RCall on a low version of julia HOT 6
- Incorrect julia compat HOT 3
- Add support for TimeZones
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rcall.jl.