Quarto: ojs_define & transpose

In this document, we show how it is possible to pass a variable from R to Observable. We deal with 3 cases:

1 - a simple variable

{r}

Here we have a variable myvar which is 12.

myvar = 12

The ojs_define instruction simply makes this variable accessible in Observable

ojs_define(myvar)

{ojs}

myvar
12

1 - a dataframe

{r}

In this second case, we import a csv file.

data <- read.csv("data/stat.csv")

As before, we use ojs_define to make this variable accessible in Observable. We rename this variable to newdata.

ojs_define(newdata = data)

{ojs}

Warning, if we visualize this data table in Observable directly, we realize that it does not really have the expected form.

newdata
Object {id: Array(209), name: Array(209), region: Array(209), pop: Array(209), gdp: Array(209), gdppc: Array(209), year: Array(209)}

Thankfully, the transpose instruction allows you to convert the table to the correct format.

data = transpose(newdata)
data
data = Array(209) [Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, …]
Array(209) [Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, …]
Inputs.table(data)
idnameregionpopgdpgdppcyear
AFGAfghanistanAsia38,928,34119,807,067,268508.812,020
AGOAngolaAfrica32,866,26862,306,913,4441,895.772,020
ALBAlbaniaEurope2,837,74314,799,615,0975,215.282,020
ANDAndorraEurope77,1463,155,065,48840,897.332,019
AREUnited Arab EmiratesAsia9,770,526421,142,267,93743,103.342,019
ARGArgentinaAmerica45,376,763383,066,977,6548,441.922,020
ARMArmeniaAsia2,963,23412,645,459,2144,267.452,020
ATAAntarcticaAntarctica
ATGAntigua and BarbudaAmerica97,9281,415,059,25914,4502,020
AUSAustraliaOceania25,687,0411,330,900,925,05751,812.152,020
AUTAustriaEurope8,917,205430,947,393,75848,327.632,020
AZEAzerbaijanAsia10,110,11642,607,176,4714,214.312,020
BDIBurundiAfrica11,890,7813,258,187,233274.012,020
BELBelgiumEurope11,555,997515,332,499,62844,594.382,020
BENBeninAfrica12,123,19815,651,545,2091,291.042,020
BFABurkina FasoAfrica20,903,27817,369,059,295830.932,020
BGDBangladeshAsia164,689,383324,239,176,7651,968.792,020
BGRBulgariaEurope6,927,28869,105,101,0909,975.782,020
BHRBahrainAsia1,641,16438,474,521,27723,443.432,019
BHSBahamasAmerica393,24811,250,000,00028,607.92,020
BIHBosnia and HerzegovinaEurope3,280,81519,788,422,2486,031.562,020
BLRBelarusEurope9,398,86160,258,239,0566,411.232,020
BLZBelizeAmerica397,6211,763,696,1194,435.622,020

3 - a spatial data frame (sf)

{r}

In this third case, we import a geopakage thanks to the library sf, containing the countries of the world.

library("sf")
countries <- st_read("data/countries.gpkg", quiet = T)
plot(st_geometry(countries))

To create a map in Observable, we first need to convert this data set to geojson format. To do this, we use the geojsonsf library. Then, the ojs_define() instruction allows to define this variable within ojs cells.

library("geojsonsf")
ojs_define(geo = sf_geojson(countries))

{ojs}

Note that with ojs_define, we have passed the variable geo as a string and not actually as an object.

geo.substr(1, 300)
`"type":"FeatureCollection","features":[{"type":"Feature","properties":{"ISO3":"GNQ","NAMEen":"Equatorial Guinea","NAMEfr":"Guinée-Équatoriale"},"geometry":{"type":"MultiPolygon","coordinates":[[[[11.322078491,2.165760396],[11.336341187,0.999164937],[9.8043711812,0.9983539399],[9.3466903,1.181708075]`

The first thing to do here is to transform our string into a real object. To do this, we use the javascript statement JSON.parse.

countries = JSON.parse(geo) 
countries
countries = Object {type: "FeatureCollection", features: Array(209)}
Object {type: "FeatureCollection", features: Array(209)}

Now everything is ok to make a map in Observable. See more here.

bertin = import('https://cdn.skypack.dev/bertin@0.9.12')
bertin.draw({
  layers: [
    {
      geojson: countries,
      tooltip:["$ISO3","$NAMEen"]
    }
    ]
})

4 - Another solution

Another way to pass variables and data from R to Observable is to save and then import data.

{r}

As before, we import a geopackage in R with sf.

countries <- st_read("data/countries.gpkg", quiet = T)

Then we convert it to geojson and save it in the data directory.

write(sf_geojson(countries), "data/world.geojson")

{ojs}

In observable, we just have to import this data file in geojson (or other) format.

world = FileAttachment("data/world.geojson").json()
world = Object {type: "FeatureCollection", features: Array(209)}

Let’s take a look at it!

bertin.quickdraw(world)

That’s all folks!