Over Christmas break I teased some screencaps:
A more refined #rstats #swift "SwiftR" example. Simple Image view + some text views, a color picker and a button that runs
R-in-Swift code (like {reticulate} does for Python in R)
Note no ssd/hd storage round-trip for the plot.
Code snippet: https://t.co/fWaHnztUgd pic.twitter.com/y5m1I16tCB
— Caliban's War (@hrbrmstr) December 28, 2020
Final teaser for #rstats R-in-Swift (SwiftR) since I _think_ I've ❌'d all memory leaks and refined the example project. The displayed 10,… numbers come right from sample()'d R vector and the fill color live refreshes fast b/c {magick} is magical. Shld have repo up Thu. pic.twitter.com/boGa5ej9FZ
— Caliban's War (@hrbrmstr) December 29, 2020
of some almost-natural “R” looking code (this is a snippet):
Button("Run") {
do { // calls to R can fail so there are lots of "try"s; poking at less ugly alternatives
// handling dots in named calls is a WIP
_ = 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 initialiation 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! `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
} catch {
}
}
that works in Swift as part of a SwiftUI app that displays a ggplot2 plot inside of a macOS application.
It doesn’t shell out to R, but uses Swift 5’s native abilities to interface with R’s C interface.
I’m not ready to reveal that SwiftR code/library just yet (break’s over and the core bits still need some tweaking) but I can provide some interim resources with an online book about working with R’s C interface from Swift on macOS. It is uninspiringly called SwiftR — Using R from Swift.
There are, at present, six chapters that introduce the Swift+R concepts via command line apps. These aren’t terribly useful (shebanged R scripts work just fine, #tyvm) in and of themselves, but command line machinations are a much lower barrier to entry than starting right in with SwiftUI (that starts in chapter seven).
FIN
If you’ve wanted a reason to burn ~20GB of drive space with an Xcode installation and start to learn Swift (or learn more about Swift) then this is a resource for you.
The topics in the chapters are also a fairly decent (albeit incomplete) overview of R’s C interface and also how to work with C code from Swift in general.
So, take advantage of the remaining pandemic time and give it a 👀.
Feedback is welcome in the comments or the book code repo (book source repo is in progress).
Hope everyone has a safe and strong new year!
One Trackback/Pingback
[…] by data_admin [This article was first published on R – rud.is, and kindly contributed to R-bloggers]. (You can report issue about the content on this page […]