[R-SIG-Mac] Swift + embedded R
Bob Rudis
bob @end|ng |rom rud@|@
Sat Jan 16 19:20:01 CET 2021
Hey folks,
In case there's any interest in using embedded R with Swift/SwiftUI,
I've started a blogdown series on that very thing.
Updates will be over at https://rud.is/books/swiftr/ & the associated
repo is at hrbrmstr/swiftr-book-examples
The book and repo are leading up to an eventual release of two
(Swift/C) packages that will make the bridge easier to integrate into
macOS Xcode Swift projects.
That library will have two modes. One will be the traditional way
embedded R works now with C code (Rf_…, SEXPs, etc).
The other uses a new/recent capability of Swift that makes the
language a bit more dynamic (at the cost of some type safety which is
sad but useful enough to make it cool).
That second mode will make Swift code like this possible:
_ = try R.evalParse("options(tidyverse.quiet = TRUE )")
// in practice this wld be called once in a model
try R.library("ggplot2")
try R.library("hrbrthemes")
try R.library("magick")
// can mix initialization of an R list with Swift and R objects
let mvals: RObject = [
"month": [ "Jan", "Feb", "Mar", "Apr", "May", "Jun" ],
"value": try R.sample(100, 6)
]
// ggplot2 ex. `mvals` is above, `col.hexValue` comes from the color picker
// can't do R.as.data.frame b/c "dots" so this is a deliberately
exposed alternate call
let gg = try R.ggplot(R.as_data_frame(mvals)) +
R.geom_col(R.aes_string("month", "value"), fill: col.hexValue) +
// supports both [un]named
R.scale_y_comma() +
R.labs(
x: rNULL, y: "# things",
title: "Monthly Bars"
) +
R.theme_ipsum_gs(grid: "Y")
// an alternative to {magick} could be getting raw SVG from {svglite} device
// we get Image view width/height and pass that to {magick}
// either beats disk/ssd round-trip
let fig = try R.image_graph(
width: Double(imageRect.width),
height: Double(imageRect.height),
res: 144
)
try R.print(gg)
_ = R.dev_off() // can't do R.dev.off b/c "dots" so this is a
deliberately exposed alternate call
let res = try R.image_write(fig, path: rNULL, format: "png")
imgData = Data(res) // "imgData" is a reactive SwiftUI bound
object; when it changes Image does too
All of the "R.…" calls are dynamically looked up in the embedded R session.
It's a WIP (~70% feature complete) and will be introduced in the
bookdown series and repo in a couple weeks.
It likely isn't super useful to a general audience (or perhaps only
useful to me :-) but the latest Swift 5 update made working with R
directly from Swift much, much easier than previously possible.
https://twitter.com/hrbrmstr/status/1344036731855769600?ref_src=twsrc%5Etfw
has a running example of the above code.
Cheers…
-boB
More information about the R-SIG-Mac
mailing list