Public
Edited
Oct 18, 2023
2 forks
15 stars
Insert cell
Insert cell
webR = {
// Set up webR
let { WebR, ChannelType } = await import('https://webr.r-wasm.org/latest/webr.mjs');
let webR = new WebR({ channelType: ChannelType.PostMessage });
await webR.init();

// Install and load packages
await webR.installPackages(['palmerpenguins', 'svglite']);
await webR.evalRVoid("library(palmerpenguins)");
await webR.evalRVoid("library(svglite)");
return webR;
}
Insert cell
shelter = {
// Using a webR shelter allows for webR's `captureR` to be used to capture R output
return new webR.Shelter();
}
Insert cell
{
// Capture stdout/stderr resulting from running R code
let rcode = `summary(aov(flipper_length_mm ~ species, data = penguins))`;
let { output } = await shelter.captureR(rcode, { withAutoprint: true });
// Tidy up after capturing R code
await shelter.purge();

// Merge output for display
return output.map((line) => line.data).join('\n');
}
Insert cell
// Plotting with svglite
{
let svgString = await webR.evalRString(`
s <- svgstring()
col <- c("red","green3","blue")
names(col) <- c("Adelie", "Chinstrap", "Gentoo")
pairs(penguins[3:6], main="Penguins Dataset", pch=21, bg=col[penguins$species])
s()
`);
let document = (new DOMParser).parseFromString(svgString, "image/svg+xml");
let svg = d3.select(document.documentElement).remove();
return svg.node();
}

Insert cell
{
// Logistic regression
let rcode = `
data <- penguins
data$chinstrap = data$species == "Chinstrap"
model <- glm(chinstrap ~ bill_length_mm + bill_depth_mm + body_mass_g + flipper_length_mm,
data = data, family=binomial(link="logit"))
summary(model)
`;
let { output } = await shelter.captureR(rcode, { withAutoprint: true, captureConditions: false });
await shelter.purge();
return output.map((line) => line.data).join('\n');
}


Insert cell
// Get dataset from R, convert to d3 style data, and plot
penguins = {
const ret = await webR.evalR("penguins");
const data = await ret.toJs();
const penguins = data.values[0].values.map((_, idx) => {
return {
species: data.values[0].values[idx],
island: data.values[1].values[idx],
bill_length_mm: data.values[2].values[idx],
bill_depth_mm: data.values[3].values[idx],
sex: data.values[6].values[idx],
}
});
return penguins;
}
Insert cell
Plot.dot(penguins, {
x: "bill_length_mm",
y: "bill_depth_mm",
stroke: "species", symbol: "species",
channels: {island: "island", sex: "sex"},
tip: true
}).plot({ grid: true, symbol: { legend: true } })
Insert cell
Insert cell
// Send a JS object to an R function, get JS values back
{
let rFn = await shelter.evalR('function (x) { 1 + sin(x) }');
let jsData = [0.1, 0.2, 0.3, 0.4, 0.5];

let ret = await rFn(jsData);
return ret.values;
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more