I am using R and ojs code chunks in a quarto document where I do data manipulation in R and the pass the data frame to the ojs chunk by using the ojs_define
function.
My issue is that date seems to be interpreted as string in ojs chunk. The result is bad formatting in plots.
Any tips on how to pass a date from r to ojs in a way that the ojs plot function recognizes it as a date?
Example:
---
title: "Code example"
format: html
editor: visual
execute:
echo: false
warning: false
---
```{r}
#Some data with a date column
library(tidyverse)
df<-data.frame(day=seq.Date(from=as.Date('2023-01-01'),
to=as.Date('2023-06-15'),
by='days'))%>%
mutate(values=rnorm(mean= 10, sd=2, n =n()))
#Passing this to ojs through ojs_define
ojs_define(plot_data=df)
```
```{ojs}
Chart = Plot.plot({
marks: [
Plot.line(transpose(plot_data),
{x: "day", y: "values"},
{ stroke: "black" }
)
]}
)
```
Since dates are being parsed as string when passed through the ojs_define
, we can transform back the string-dates type to datetime type in the ojs chunk.
Here we will use d3.timeParse
to create a datetime parser and will use the Arquero
library (inspired by the design of dplyr
) to derive
(i.e mutate) the day
column to have datetime values.
Two things to note here,
Arquero
work with data tables. But the plot_data
is of JSON format. So we need to transpose
it to convert it to an array of objects which then passed to aq.from
to convert as table.
To use that parser
within derive
, we need to wrap d => parse(d)
with aq.escape
---
title: "Code example"
format: html
execute:
echo: false
warning: false
---
```{r}
library(dplyr)
df <- data.frame(day = seq.Date(
from = as.Date('2023-01-01'),
to = as.Date('2023-06-15'),
by = 'days'
)) %>%
mutate(
values = rnorm(mean = 10, sd = 2, n = n())
)
ojs_define(plot_data=df)
```
```{ojs}
import { aq } from '@uwdata/arquero'
d3 = require("d3@7")
parser = d3.timeParse("%Y-%m-%d");
```
## Plot
```{ojs}
final_data = aq.from(transpose(plot_data))
.derive({ day: aq.escape(d => parser(d.day)) })
```
```{ojs}
Chart = Plot.plot({
marks: [
Plot.line(final_data,
{x: "day", y: "values"},
{ stroke: "black" }
)
]}
)
```