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

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

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

问题

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

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

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

示例:

  1. # 一些具有日期列的数据
  2. library(tidyverse)
  3. df <- data.frame(day = seq.Date(from = as.Date('2023-01-01'),
  4. to = as.Date('2023-06-15'),
  5. by = 'days')) %>%
  6. mutate(values = rnorm(mean = 10, sd = 2, n = n()))
  7. # 通过ojs_define将数据传递给ojs
  8. ojs_define(plot_data = df)
  1. Chart = Plot.plot({
  2. marks: [
  3. Plot.line(transpose(plot_data),
  4. {x: "day", y: "values"},
  5. { stroke: "black" }
  6. )
  7. ]}
  8. )
  1. <details>
  2. <summary>英文:</summary>
  3. 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.
  4. My issue is that date seems to be interpreted as string in ojs chunk. The result is bad formatting in plots.
  5. 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?
  6. Example:
  7. ~~~
  8. ---
  9. title: &quot;Code example&quot;
  10. format: html
  11. editor: visual
  12. execute:
  13. echo: false
  14. warning: false
  15. ---
  16. ```{r}
  17. #Some data with a date column
  18. library(tidyverse)
  19. df&lt;-data.frame(day=seq.Date(from=as.Date(&#39;2023-01-01&#39;),
  20. to=as.Date(&#39;2023-06-15&#39;),
  21. by=&#39;days&#39;))%&gt;%
  22. mutate(values=rnorm(mean= 10, sd=2, n =n()))
  23. #Passing this to ojs through ojs_define
  24. ojs_define(plot_data=df)
  1. Chart = Plot.plot({
  2. marks: [
  3. Plot.line(transpose(plot_data),
  4. {x: &quot;day&quot;, y: &quot;values&quot;},
  5. { stroke: &quot;black&quot; }
  6. )
  7. ]}
  8. )
  1. </details>
  2. # 答案1
  3. **得分**: 2
  4. 由于在传递给 `ojs_define` 时,日期被解析为字符串,我们可以在 ojs 块中将字符串日期类型转换回日期时间类型。
  5. 在这里,我们将使用 [`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` 列以包含日期时间值。
  6. 这里需要注意两件事:
  7. 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)。
  8. 2. 要在 `derive` 中使用该 `parser`,我们需要使用 [`aq.escape`](https://observablehq.com/@uwdata/introducing-arquero#cell-1102) 包装 `d => parse(d)`。
  9. ```markdown
  10. ---
  11. title: "代码示例"
  12. format: html
  13. execute:
  14. echo: false
  15. warning: false
  16. ---
  17. ```{r}
  18. library(dplyr)
  19. df <- data.frame(day = seq.Date(
  20. from = as.Date('2023-01-01'),
  21. to = as.Date('2023-06-15'),
  22. by = 'days'
  23. )) %>%
  24. mutate(
  25. values = rnorm(mean = 10, sd = 2, n = n())
  26. )
  27. ojs_define(plot_data=df)
  28. ```
  29. ```{ojs}
  30. import { aq } from '@uwdata/arquero'
  31. d3 = require("d3@7")
  32. parser = d3.timeParse("%Y-%m-%d");
  33. ```
  34. ## 绘图
  35. ```{ojs}
  36. final_data = aq.from(transpose(plot_data))
  37. .derive({ day: aq.escape(d => parser(d.day)) })
  38. ```
  39. ```{ojs}
  40. Chart = Plot.plot({
  41. marks: [
  42. Plot.line(final_data,
  43. {x: "day", y: "values"},
  44. { stroke: "black" }
  45. )
  46. ]}
  47. )
  48. ```
  49. ```
  50. [![observable plot with datetime axis][1]][1]
  51. ```
  52. [1]: https://i.stack.imgur.com/ctAbL.png
  53. ```
  54. <details>
  55. <summary>英文:</summary>
  56. 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.
  57. 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.
  58. Two things to note here,
  59. 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).
  60. 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

  1. library(dplyr)
  2. df &lt;- data.frame(day = seq.Date(
  3. from = as.Date(&#39;2023-01-01&#39;),
  4. to = as.Date(&#39;2023-06-15&#39;),
  5. by = &#39;days&#39;
  6. )) %&gt;%
  7. mutate(
  8. values = rnorm(mean = 10, sd = 2, n = n())
  9. )
  10. ojs_define(plot_data=df)
  1. import { aq } from &#39;@uwdata/arquero&#39;
  2. d3 = require(&quot;d3@7&quot;)
  3. parser = d3.timeParse(&quot;%Y-%m-%d&quot;);

Plot

  1. final_data = aq.from(transpose(plot_data))
  2. .derive({ day: aq.escape(d =&gt; parser(d.day)) })
  1. Chart = Plot.plot({
  2. marks: [
  3. Plot.line(final_data,
  4. {x: &quot;day&quot;, y: &quot;values&quot;},
  5. { stroke: &quot;black&quot; }
  6. )
  7. ]}
  8. )
  1. [![observable plot with datetime axis][1]][1]
  2. [1]: https://i.stack.imgur.com/ctAbL.png
  3. </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:

确定