使用Quarto中的ojs_define从R块传递日期到ojs块

huangapple go评论83阅读模式
英文:

Passing dates from R chunk to ojs chunk using ojs_define in Quarto

问题

我正在使用R和ojs代码块在quarto文档中进行数据操作,我通过使用ojs_define函数将数据框从R传递给ojs代码块。

我的问题是日期在ojs代码块中似乎被解释为字符串。结果是图表的格式不正确。

有没有关于如何以一种方式从R传递日期到ojs,以便ojs绘图函数识别它为日期的提示?

示例:

# 一些具有日期列的数据
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()))

# 通过ojs_define将数据传递给ojs

ojs_define(plot_data = df)

Chart = Plot.plot({
  marks: [
    Plot.line(transpose(plot_data), 
      {x: "day", y: "values"}, 
      { stroke: "black" }
    )
  ]}
)

<details>
<summary>英文:</summary>

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: &quot;Code example&quot;
format: html
editor: visual
execute:
  echo: false
  warning: false
---

```{r}
#Some data with a date column
library(tidyverse)

df&lt;-data.frame(day=seq.Date(from=as.Date(&#39;2023-01-01&#39;), 
                            to=as.Date(&#39;2023-06-15&#39;), 
                            by=&#39;days&#39;))%&gt;%
  mutate(values=rnorm(mean= 10, sd=2, n =n()))

#Passing this to ojs through ojs_define

ojs_define(plot_data=df)

Chart = Plot.plot({
  marks: [
    Plot.line(transpose(plot_data), 
      {x: &quot;day&quot;, y: &quot;values&quot;}, 
      { stroke: &quot;black&quot; }
    )
  ]}
)

</details>


# 答案1
**得分**: 2

由于在传递给 `ojs_define` 时,日期被解析为字符串,我们可以在 ojs 块中将字符串日期类型转换回日期时间类型。

在这里,我们将使用 [`d3.timeParse`](https://github.com/d3/d3-time-format#timeParse) 来创建一个日期时间解析器,并使用 [`Arquero`](https://observablehq.com/@uwdata/introducing-arquero) 库(灵感来自于 `dplyr` 的设计)来 [`派生`](https://observablehq.com/@uwdata/introducing-arquero#cell-351)(即变异)`day` 列以包含日期时间值。

这里需要注意两件事:

1. [`Arquero` 适用于数据表](https://observablehq.com/@uwdata/introducing-arquero#cell-24)。但是 `plot_data` 是 JSON 格式的。因此,我们需要将其 [`转置`](https://quarto.org/docs/interactive/ojs/data-sources.html#transpose) 以将其转换为对象数组,然后将其传递给 [`aq.from` 以将其转换为表格](https://observablehq.com/@uwdata/introducing-arquero#cell-64)。

2. 要在 `derive` 中使用该 `parser`,我们需要使用 [`aq.escape`](https://observablehq.com/@uwdata/introducing-arquero#cell-1102) 包装 `d => parse(d)`。

```markdown
---
title: "代码示例"
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");
```

## 绘图

```{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" }
    )
  ]}
)
```
```

[![observable plot with datetime axis][1]][1]
```

[1]: https://i.stack.imgur.com/ctAbL.png
```

<details>
<summary>英文:</summary>

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`](https://github.com/d3/d3-time-format#timeParse) to create a datetime parser and will use the [`Arquero`](https://observablehq.com/@uwdata/introducing-arquero) library (inspired by the design of `dplyr`) to [`derive`](https://observablehq.com/@uwdata/introducing-arquero#cell-351) (i.e mutate) the `day` column to have datetime values.

Two things to note here, 

1. [`Arquero` work with data tables](https://observablehq.com/@uwdata/introducing-arquero#cell-24). But the `plot_data` is of JSON format. So we need to [`transpose`](https://quarto.org/docs/interactive/ojs/data-sources.html#transpose) it to convert it to an array of objects which then passed to [`aq.from` to convert as table](https://observablehq.com/@uwdata/introducing-arquero#cell-64).

2. To use that `parser` within `derive`, we need to wrap `d =&gt; parse(d)` with [`aq.escape`](https://observablehq.com/@uwdata/introducing-arquero#cell-1102)


title: "Code example"
format: html
execute:
echo: false
warning: false

library(dplyr)

df &lt;- data.frame(day = seq.Date(
        from = as.Date(&#39;2023-01-01&#39;),
        to = as.Date(&#39;2023-06-15&#39;),
        by = &#39;days&#39;
      )) %&gt;%
  mutate(
    values = rnorm(mean = 10, sd = 2, n = n())
  )

ojs_define(plot_data=df)
import { aq } from &#39;@uwdata/arquero&#39;
d3 = require(&quot;d3@7&quot;)
parser = d3.timeParse(&quot;%Y-%m-%d&quot;);

Plot

final_data = aq.from(transpose(plot_data))
  .derive({ day: aq.escape(d =&gt; parser(d.day)) })
Chart = Plot.plot({
  marks: [
    Plot.line(final_data, 
      {x: &quot;day&quot;, y: &quot;values&quot;}, 
      { stroke: &quot;black&quot; }
    )
  ]}
)

[![observable plot with datetime axis][1]][1]


  [1]: https://i.stack.imgur.com/ctAbL.png

</details>



huangapple
  • 本文由 发表于 2023年6月18日 17:51:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76499928.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定