Home > Software design >  Pass R object to Observable in Quarto
Pass R object to Observable in Quarto

Time:09-28

I am trying to use R and Observable together in a quarto doc as per: https://quarto.org/docs/interactive/ojs/

As far as I can tell, one uses the ojs_define function to make data available to observable. So for the example below I am trying that with palmerpenguins::penguins_raw:

---
title: "Untitled"
format: html
---

```{r}
ojs_define(data = palmerpenguins::penguins_raw)
```


```{ojs}
viewof bill_length_min = Inputs.range(
  [32, 50], 
  {value: 35, step: 1, label: "Bill length (min):"}
)
viewof islands = Inputs.checkbox(
  ["Torgersen", "Biscoe", "Dream"], 
  { value: ["Torgersen", "Biscoe"], 
    label: "Islands:"
  }
)
```


```{ojs}
filtered = data.filter(function(penguin) {
  return bill_length_min < penguin.bill_length_mm &&
         islands.includes(penguin.island);
})
```

```{ojs}
Plot.rectY(filtered, 
  Plot.binX(
    {y: "count"}, 
    {x: "body_mass_g", fill: "species", thresholds: 20}
  ))
  .plot({
    facet: {
      data: filtered,
      x: "sex",
      y: "species",
      marginRight: 80
    },
    marks: [
      Plot.frame(),
    ]
  }
)
```

However when I render I get these types of errors: https://i.stack.imgur.com/F09CA.png

Any idea what I might be doing wrong here?

CodePudding user response:

There are a few things to note,

Firstly, you are using palmerpenguins::penguins_raw data, which has no columns named bill_length_min, bill_length_mm. Maybe you are intending to use palmerpenguins::penguins.

Secondly, you need to do transpose(data) before doing filter operation in the ojs chunk. Because from the documentation,

the Plot function expects data by row rather than by column, so we transpose() it before filtering


---
title: "Untitled"
format: html
---

```{r}
ojs_define(data = palmerpenguins::penguins)
```


```{ojs}
viewof bill_length_min = Inputs.range(
  [32, 50],
  {value: 35, step: 1, label: "Bill length (min):"}
)
viewof islands = Inputs.checkbox(
  ["Torgersen", "Biscoe", "Dream"],
  { value: ["Torgersen", "Biscoe"],
    label: "Islands:"
  }
)
```


```{ojs}
filtered = transpose(data).filter(function(penguin) {
  return bill_length_min < penguin.bill_length_mm &&
         islands.includes(penguin.island);
})
```

```{ojs}
Plot.rectY(filtered,
  Plot.binX(
    {y: "count"},
    {x: "body_mass_g", fill: "species", thresholds: 20}
  ))
  .plot({
    facet: {
      data: filtered,
      x: "sex",
      y: "species",
      marginRight: 80
    },
    marks: [
      Plot.frame(),
    ]
  }
)
```


  • Related