Working with Quarto

How to generate reproducible reports and computational notebooks

Published

27-Nov-2024

1 Introduction

The Quarto format (.qmd) is a multi-functional format, which is especially useful for scientific coding and analyses. Quarto documents can be used both to save and execute code as well as generating reports in various output formats. This is done by mixing markdown and so-called code chunks in the same document (we have course materials for markdown if you are unfamiliar with this format). The code itself as well as the output it generates can be included in the final report. Not only can Quarto work great for scientific coding, but can also be used for things such as presentation and websites - this entire workshop website is, in fact, created using only Quarto!

Quarto makes your analysis more reproducible by connecting your code, figures and descriptive text. You can use it to make reproducible reports, rather than e.g. copy-pasting figures into a Word document. You can also use it as a notebook, in the same way as lab notebooks are used in a wet lab setting (or as we utilise Jupyter notebooks in the tutorial after this one). Quarto itself does not require any particular programming language to be installed - any language you want to use can be installed separately. The currently supported languages are R, Python, Julia and Observable. Quarto is fully compatible with both R Markdown and Jupyter documents.

This tutorial depends on files from the course GitHub repo. Take a look at the setup for instructions on how to set it up if you haven’t done so already. Place yourself in the workshop-reproducible-research/tutorials/quarto/ directory, activate your quarto-env Conda environment and start your text editor or IDE of choice.

A note on R Markdown

Quarto is an evolution of the R Markdown format, which was previously used in this course. While R Markdown is a widely-used and excellent software for code and reports, Quarto is most easily thought of as “R Markdown 2.0”. If you’re familiar with R Markdown, you will find Quarto to be highly similar. The creators of both Quarto and R Markdown (Posit) have stated that R Markdown is not going to be deprecated, but most newer features will only come to Quarto. This means that if you’ve used R Markdown in the past now is a good time to make the switch, but you don’t have to. You can check out the Quarto website for more in-depth discussions regarding Quarto/R Markdown (dis-)similarities.

2 The basics

Let’s start with creating basic Quarto document that we can work with.

2.1 Creating Quarto documents

Quarto documents are just plain text files with the .qmd extension. Create a new file called e.g. quarto-tutorial.qmd and copy the following into it:

---
title: "Untitled Quarto Document"
author: "Jane Doe"
format: html
---

This is a so-called YAML header, which is where we specify the general settings of the document in the form of key: value. The title and author are just what they sound like, while the format field specifies what type of output you want the final report to be in (alternatives include pdf, revealjs and many others). Here we have specified that we want HTML output, which is perhaps the most useful for scientific computing.

  • Change the title to My first Quarto document and the author to your name.

Let’s add some actual content to the document, starting with some basic markdown:

  • Add some text into your Quarto document (including an empty line between the YAML header and the text), e.g. the following:
This is my first Quarto document!

# This is a header

This is where I'll soon add some *code* related to the first header.

Let’s see what this document looks like when it’s rendered into HTML by Quarto:

  • Go to the command line and type quarto render quarto-tutorial.qmd.
Rendering

If you’re using e.g. RStudio or VSCode to edit your Quarto document you might have access to a render button, which means you don’t have to run the above command from the command line if you prefer.

Open your new quarto-tutorial.html file that was created and see what it looks like. It’s only markdown content so far, so let’s add some R code using a code chunk:

```{r}
Sys.Date()
```

Notice that we delimit the code chunk from the rest of the document’s contents using three backticks (```) and specify the R language using curly brackets ({r}). The code itself just prints the current date.

  • Render the document again and see what it looks like.

You can also name chunks by adding it after the language:

```{r}
Sys.Date()
```

This is useful for debugging when something has gone wrong, since it’ll be easier to see exactly which code chunk an error happened (instead of just showing the chunk as a number).

We can also get in-line code using {r} <R CODE>, like so:

The current date is `{r} Sys.Date()`.
  • Add the example above and render the document again to make sure it worked.

2.2 Previewing documents

Quarto has a highly useful command for when you’re working on a document: preview. It’s essentially a live preview of the document you’re working on that will automatically render when you introduce changes to the document.

  • Type quarto preview quarto-tutorial.qmd in the command line.

Your default web browser should now have opened a new window with your rendered document, while your command line should say something like the following:

Watching files for changes
Browse at http://localhost:4175/

You can’t type new commands at the moment, because the Quarto Preview command is still running - it’s watching for any new changes to the Quarto document you specified.

  • Change or add some markdown text to your Quarto document, e.g. This is a code chunk instead of the previous text under the first header. Make sure you save the document.

The HTML document in your browser should have updated to reflect your newest changes automatically. Previewing documents is great when you want to have continuous feedback to the changes you make and can make the process of writing more seamless, since you don’t have to manually render all the time. Previewing will still render the entire document, however, meaning that if you have some heavy computations you might not want to re-render on every single save. For those cases you might instead prefer to stick with manual rendering when you are satisfied with multiple changes. You can abort a preview like any on-going command, e.g. using Ctrl-C.

In the rest of the tutorial it’s up to you whether you want to use preview or not - the tutorial will just mention when it’s time to render, you decide how that’s done.

2.3 Rendering to PDF

So far we’ve only rendered to HTML, but sometimes you prefer a PDF. This entails changing the format option in the YAML header:

  • Change the format to pdf in the header and render your document.

You can add any raw LaTeX commands you want to your document when you’re rendering to PDF, e.g. \footnotsize to change the font size. You also have LaTeX-specific settings, such as setting the geometry for the whole document or specifying a citation method. While the details of LaTeX are outside the scope of this course, it’s useful to be aware of this functionality of Quarto so that you may use it if you already know LaTeX or if you want to learn it.

Switch back to HTML rendering before you move on.

2.4 Languages

The examples so far have been using R, but we could just as easily have used Python. All we have to do is to change our code chunk to specify {python} as language and its content to be the equivalent Python code:

```{python}
from datetime import date
print(date.today())
```
  • Change the code chunk to the above Python chunk instead and render your document again.
A note on Python in-line code

Quarto support for in-line python code was added in version 1.4, so if you’re using an older version of Quarto simply remove the in-line code example. You can check your quarto version by running quarto --version on the commandline. As of this writing, the 1.4 version of Quarto can be obtained from the pre-release page: https://quarto.org/docs/download/prerelease

If you’re using Quarto version 1.4 or higher and want to try the in-line code example above for Python, change the line to:

The current date is `{python} date.strftime(date.today(), format="%Y-%m-%d")`

So far we’ve had Quarto automatically determine which language engine should be used, which it detects through the code chunks we’ve written. We can also do this explicitly by adding engine: knitr or engine: jupyter to the YAML header.

  • Explicitly add engine: jupyter to your YAML header and render the document.
Making sure your Jupyter engine is recognised

Quarto attempts to identify a suitable Jupyter engine for your system when you include Python code chunks. However, if you want to use Jupyter available in a specific conda environment (e.g. your quarto-env environment) you need to take some extra steps. Please visit this link and follow steps 1-4. In the final step, check for the name of the kernel matching your quarto-env conda environment, e.g.

$ jupyter kernelspec list
Available kernels:
...
 conda-env-quarto-env-py    /Users/<your-user-name/Library/Jupyter/kernels/conda-env-quarto-env-py

Using the example output from above we can add the following to the YAML header of our Quarto document:

jupyter:
 kernelspec:
   display_name: Python 3
   language: python
   name: conda-env-quarto-env-py

It can be useful to explicitly set the language for the document, as it makes it clearer from just the YAML header what language will be used. There are also more language-related options for Quarto, but we’ll save those for later in the tutorial.

Quick recap

In this section you learned how to create, edit and render basic Quarto documents using different languages.

3 Code chunks

Sometimes you want to add chunk options to the code chunks in your Quarto documents. They are also in YAML format and are prefixed with a special type of comment (#|). It can look something like this:

```{python}
#| echo: false
from datetime import date
print(date.today())
```
  • Add the chunk option above to your document and render the document again.

Notice how we no longer see the code itself, just the output? This is because the echo option specifies just that: whether we see the code or not. There are a number of such chunk options that are useful to know about:

Chunk option Effect
echo Include the chunk code in the output.
eval Evaluate the code chunk.
output Include the results of executing the code in the output.
warning Include warnings in the output.
error Include errors in the output (note that this implies that errors executing code will not halt processing of the document).
include Prevent both code and output from being included.
  • Check what happens if you change echo: False to eval: False.

Now the code in the code chunk is not run, which means that if you previously added the python inline code it will no longer work because it depends on date from the datetime module that we import in the code chunk. Remove the inline code snippet if you added it. Then try rendering again. Now you should see the code itself but it won’t be run and therefore has no output.

3.1 Figure options

There are also options related to figures, but for that we need to actually have some code that produces a figure.

  • Change the YAML header to use R instead of Python, remove the Python code chunk and replace it with the following (don’t worry if you don’t understand the R code itself, it’s just as example):
```{r}
library("ggplot2")
library("palmerpenguins")
data(penguins, package = "palmerpenguins")
ggplot(penguins, aes(x      = bill_length_mm,
                     y      = body_mass_g,
                     colour = species)) +
    geom_point(size = 2) +
    theme_bw() +
    labs(x      = "Bill length (mm)",
         y      = "Body mass (g)",
         colour = "Species") +
    ggtitle("Penguin weight and bill length") +
    theme(plot.title = element_text(hjust = 0.5)) +
    scale_colour_manual(values = c("#c1dea0", "#85be42", "#425f21"))
```

When you’ve rendered the document you should see both the code and a figure using the Palmer Penguins dataset. You should also see a warning along the lines of Removed 2 rows containing missing values.

  • Suppress the warning by adding #| warning: false as a chunk option and render.

There are two chunk options related to figure sizes: fig-width and fig-height (expressed in inches). These allow you to experiment with your figures and make them look the way you want.

  • Add both the fig-width: 10 and fig-height: 5 chunk options and render.
Note

These two chunk options are only available when using the Knitr engine, not for Jupyter. There is a way to set these for the whole document with Jupyter, though, which we’ll talk more about in the next section of the tutorial.

You can also add captions and alt text using fig-cap and fig-alt, respectively.

  • Add a suitable caption and alt text to the figure and render.

If you want to place the caption in the margin of your document you can use the cap-location chunk option.

  • Add cap-location: margin to your chunk options and render.
Note

On some quarto versions the cap-location: option may not work as expected. If you experience this, try also adding #| label: fig-penguins to the chunk.

3.2 Cross-references

A convenient way to be able to refer to figures in text is by adding a figure label, which will automatically add a figure number before your caption.

  • Add a suitable label, e.g. label: fig-penguins to the chunk options.

Cross-references use the @ symbol and the corresponding label. You can thus write some markdown outside of a code chunk and refer to e.g. @fig-penguins, as per the example here. This is extremely useful if you’re writing a paper or a report where you want to refer to figures and content in the markdown text. Quarto even adds a clickable link to the figure itself as well!

3.3 Sub-figures

It’s also possible to create sub-figures using Quarto, instead of using whatever plotting library that your created the figures with.

  • Add the following (almost identical) code at the bottom of the chunk you already have:
ggplot(penguins, aes(x      = bill_depth_mm,
                     y      = body_mass_g,
                     colour = species)) +
    geom_point(size = 2) +
    theme_bw() +
    labs(x      = "Bill depth (mm)",
         y      = "Body mass (g)",
         colour = "Species") +
    scale_colour_manual(values = c("#c1dea0", "#85be42", "#425f21"))
  • Also add the following to the chunk options:
#| fig-subcap:
#|     - Bill length vs. body mass
#|     - Bill depth vs. body mass

You should now see that we have two figures with separate sub-captions as well as the overall figure caption we previously added. We can also control the layout of these figures using the layout-ncol chunk option.

  • Add a layout-ncol: 2 chunk option and render the document.

We now have a different, two-column layout instead, but whether you prefer this or just a one-column layout is up to you.

3.4 Tables

Tables work much in the same way as figures. It might, in our example, be nice to add a table with the data we previously plotted.

  • Add the following code chunk to your document and render it:
```{r}
#| label: tbl-penguins
#| tbl-cap: Palmer penguins bill length, width and body mass.
#| tbl-cap-location: margin
knitr::kable(
    penguins[1:10, c("species", "bill_length_mm", "bill_depth_mm", "body_mass_g")],
    col.names = c("Species", "Bill length (mm)", "Bill depth (mm)", "Body mass (g)")
)
```
Quick recap

In this section you learned several chunk, figure and table options, how cross-referencing works and how to add sub-figures.

4 Document options

So far we’ve mostly worked with chunk options, which are specific to the chunk they appear in. You can set many of these at the global document level, however, and there are also some options specifically for tailoring the document as a whole, regardless of chunk content.

We’ve already looked at some global options, such as title, author, format and engine. Something that would go nicely with the first two is the date option. You could just write the actual date if you like, or you can use the today option:

  • Add the following to the options: date: today

4.1 Code folding

A useful option we haven’t touched already is the code-fold option. This and similar global options are specified nested inside the format option, like so:

format:
    html:
        code-fold: true
  • Add the code-fold option to your document and render it.

This can be a nice default to use in scientific reports, as it hides the code by default but is always there for those who want to inspect it. You can also use the code-summary chunk option to specify a different text to show with the folded code instead of the default Code, e.g. code-summary: Click to show code.

If you want to add the code-summary option to all chunks you can add the following to the yaml header:

language:
  code-summary: Click to show code

You can also add the code-tools option, which will add a drop-down menu to toggle visibility of all code as well as the ability to view the source of the document.

  • Add the code-tools: true option and render the document.

4.2 Table of contents

Another useful document option is to add a table of contents, which can be done with the toc option. This will automatically populate the table of contents using the headers from your document.

  • Add some more headings and/or sub-headings to your document.

  • Add the toc: true option to the html format and render.

The table of contents is to the right of the document by default, but you can change it using toc-location. The toc-depth allows you to control how many sub-heading levels are included in the table of contents.

  • Add toc-location: left and toc-depth: 2 to your document and render it.

Having the table of contents on the left can be useful if you are using the margins for something, such as we are doing in this tutorial. You can similarly add section numbering using number-sections and number-depth. Smooth scrolling is not enabled by default, but you can add it using smooth-scroll: true. You can change the title of the table of contents using toc-title.

  • Add section numbers, depth, smooth scrolling and a different table of contents title to your document and render it.

4.3 Themes

Quarto has a lot of themes available for it.

  • Add theme: flatly under the HTML format option and render.

If you want to get real advanced you can play around with lots of details regarding the themes and adjust as you see fit, or even just create your own theme. This is a bit too advanced to go through here, but you can read about it more in the official documentation.

4.4 Global chunk options

The chunk options we learnt about in the previous section of this tutorial can also be specified on the global document level. Instead of specifying e.g. warning: false or fig-height: 5 in individual chunks we can add it to the main YAML header in the same manner as for e.g. code folding or table of contents. We’ll still have to specify options like labels or captions at the chunk-level, though.

  • Add warning: false to your document header and remove it from the penguin figure chunk you already have.

4.5 Embedding HTML resources

When rendering HTML documents you get any figures and other resources in a <document-name>_files/ directory, which is not always desirable. It’s easier to move the HTML around if all figures etc. are embedded directly in the HTML itself, which can be done by specifying embed-resources: true in the HTML format options. This option is false by default, meaning that you’ll also have to include the previously mentioned directory if you want to share the HTML with anybody.

  • Remove the <document-name>_files/ directory, refresh the rendered document and see what happens.

  • Add the embed_resources option and render your document again.

What happened first is that your figures should have disappeared when you deleted the resources directory. Embedding resources and rendering again should not re-create this directory, so now you’ll just have a stand-alone HTML file that is more portable than before.

4.6 Multiple formats

So far we’ve mostly been working with HTML output, but you don’t need to limit yourself to a single output format if you don’t want to.

  • Add the docx: default line in the format: part of your YAML header and render your document.

You should have gotten two separate output files now: a HTML and a DOCX (Word) file. You can specify further options for any of the formats you include, instead of just using the default settings as in this example.

  • Render your document again, but supply the --to html flag.

This will only render to the specified output format, which is highly useful when you want to write a Quarto document with more than one format but not always render them all.

4.7 Parameters

The last document-wide option we’ll touch on is parameters. This is useful for when you want to be able to run the same document with different parameters or options for some computations. How parameters are specified depends on which engine you’re using. With Knitr you can specify parameters using the params option:

  • Add the following code to your YAML header:
params:
    point_size: 2
  • Also change the hard-coded geom_point(size = 2) to geom_point(size = params$point_size) in the two ggplot calls in the first code chunk.

We have thus specified a parameter called point_size in the YAML header and referred to it in the code using params$point_size. You can now change this parameter at run-time by supplying the -P <param>:<value> (or --execute-param) flag to quarto render.

Notice that this won’t work if you want to use a parameter to control e.g. a chunk option like layout-ncol. For this we need to use an in-line code expression: #| layout-ncol: !expr params$ncols.

  • Add a parameter for the layout-ncol chunk option to the YAML header
  • Also add the layout-ncol chunk option to the figure chunk using the syntax above and render to make sure it works.

Note that to modify multiple parameters at run-time you have to use the -P param:value flag multiple times, like so:

quarto render quarto-tutorial.qmd -P point_size:4 -P ncols:1

If you’re using the Jupyter engine you can instead specify parameters by designating a single cell as a parameter cell, like so:

```{python}
#| tags: [parameters]
point_size = 2
```

You can also specify parameters in a params.yml file and instruct quarto to use them with the --execute-params params.yml flag when rendering. Note that the parameters must be defined in the document (in the YAML header when using the knitr engine, or in a cell when using the jupyter engine). Pointing quarto to a params.yml file with --execute-params only overrides them when rendering.

Using parameters is extremely useful when you’re using a workflow manager system (e.g. Snakemake or Nextflow), since you can easily specify sample-specific parameters from the command line directly from your workflow manager.

Quick recap

In this sections we covered a number of document-wide options, including code-folding, table of contents, theming, HTML portability, using multiple output formats and parameters.

5 Presentations

Quarto can also be used to create presentations in multiple formats such as reveal.js (HTML), beamer (PDF) and pptx (PowerPoint) - the most powerful of these formats by far is the first one. Creating presentations with Quarto is quite similar to creating general Quarto documents, with some added features to keep in mind.

5.1 Slides

The first thing that’s needed for creating a presentation is deciding what constitutes a slide. The default is that slides are delimited by a document’s header levels.

  • Render your document using the --to revealjs flag and open it.

You should now have the same document we’ve been working on for this tutorial in presentation format! You can step through the slides using the arrow keys, press F to go into full-screen mode, S to view speaker notes, M for the menu (you can also click in the lower left corner to get this menu) and ESC to go back.

If you’ve followed along you should have one level-1 header (#) and two level-2 headers (##). Notice that the level-1 header here will render as a blank page with just the header content on it, while the level-2 headers will render as normal slide headers. This all looks quite nice, and we didn’t even have to change a thing! Disregard that the table on the last slide doesn’t fit for now, we’ll get back to it later. Another method of delimiting slides is using a horizontal rule, ---, which allows you more fine-grained control over slides and their content (and is especially useful if you want to have a slide without a title).

5.2 Divisions

There are many ways you can add presentation-specific content to your slides, some of which you’d recognise from e.g. PowerPoint functionality.

So called “divisions” or “divs” allow you to control the appearance of content in your slides.

Let’s fix that issue with the table that was larger than the page. The problem here is one of content overflow, which can be fixed by adding a special {.smaller} div.

Note

Divs do not work for level1 headings (starting with a single #).

  • Add the {.smaller} div to the table header (it should read something like ## A table {.smaller}) and render.

That should have automatically re-sized the table to fit into the slide. Another way to solve this is to make slide content scrollable.

  • Change the {.smaller} div to a {.scrollable} div and render.

Instead of re-sizing the table we now get the ability to scroll down it instead; whichever solution you prefer is up to you.

Adding divisions of various types like this is a common thing for Quarto presentations. Another common presentation-functionality is incremental lists, which can also be achieved with divisions. When adding a division to slide content we specify the division’s content in a manner similar to a code chunk, like in the following example:

## Penguin species

::: {.incremental}
 - Adelie
 - Chinstrap
 - Gentoo
:::
  • Add the code above to your document and render it.

Stepping through incremental content works the same as for stepping through slides, i.e. using the arrow keys.

  • Render your document to html instead of revealjs.

Notice that Quarto rendered the HTML document just fine, even though you now have some presentation-specific code? This allows you to switch between the formats on-demand without having much overhead or format-specific code, which is great when you want to present your work without having to whip out a full-fledged presentation and all the work that goes into that!

There are other useful divisions as well, including {.notes} (speaker notes), {.aside} (additional commentary similar to footnotes), {.footer} (slide footers), which you can add in the same way as we did for the incremental list above.

  • Pick one of the above-mentioned divisions to add to your presentation and render it.
Note

The notes and footer divisions will appear as normal Markdown text when rendering to HTML, while asides will appear in the margin. These divisions thus represent cases you might want to avoid if you want to be completely format-agnostic.

5.3 Presentation options

Just like the other formats you can specify presentation-specific options at the document-level using the YAML header. You could, for example, add the {.scrollable} or {.smaller} div to the entire document.

  • Add the revealjs format to the YAML header as well as a scrollable: true option to it.

You can also specify one of the built-in themes here.

  • Add theme: simple to your YAML header and render.

You can find the entire list of themes at the Quarto website.

5.4 Multiple columns

Sometimes you’ll want to have more than one column in your presentation, which is done with the {.columns} and {.column} divisions. The former specifies that a section with multiple columns is starting, while the second specifies when each column starts, like so:

:::: {.columns}

::: {.column}
Left column
:::

::: {.column}
Right column
:::

::::
  • Add multiple columns with some content to your presentation and render it.

You can also control the widths of these columns using e.g. {.column width="40%"}.

Note

The {.columns} div also works for a normal HTML render, so it’ll look the same regardless of whether you output as a document or a presentation.

5.5 Fragments

We’ve already learnt how to get incremental lists working, but what about general content we want to incrementally step through? This is done with the {.fragment} div.

  • Add a {.fragment} div to some slide content and render.

Fragments are similar to “animations” from PowerPoint and come with lots of built-in variations, e.g. fade-out, grow, strike and several others.

  • Add a fragment variant to your content, e.g. {.fragment .grow} and render your document.

You can also control the order in which fragments appear using the fragment-index=<NUMBER> option.

  • Create a new slide and add some content with a different order of appearance than the order of the code. If you need help or inspiration, click below.
## Why Palmer Penguins?

::: {.fragment fragment-index=2}
![](https://allisonhorst.github.io/palmerpenguins/logo.png){fig-align="center"}
:::

::: {.fragment fragment-index=1}
The goal of `palmerpenguins` is to provide a good dataset for data exploration
and visualization, as an alternative to `iris.`
:::
Quick recap

In this section we covered how to create presentations using Quarto, including how to add various divisions, global slide-options, multiple columns and fragments.

6 Extra material

The following material contains some more advanced things that you can do with Quarto but are not really part of the core of the Quarto material. It’s a mix of various functionalities, and you don’t have to go through it if you don’t want to.

If you’re interested in learning more about Quarto in general, here are some reading tips:

6.1 Tabsets

Sometimes you’ll want to present the same content in different ways, e.g. the equivalent code in different languages. Look at the following toy example:

::: {.panel-tabset}
## R
```{r}
words <- c("Foo", "bar")
print(paste(words), collapse = ' ')
```

## Python
```{python}
words = ["Foo", "bar"]
print(' '.join(words))
```
:::

Try adding that to a document and see that you’ll get a set of tabs that change the content of the code chunk to the respective language. This is not only useful for showing different languages, but can be used for other situations as well. For example, you might want to run different analyses and show them in different tabs, or even show different interactive elements in separate tabs.

6.2 Callouts

If you’re writing some sort of documentation, tutorial or just want to draw special attention to something, callouts are here for you. They render as a coloured block with a header and content. There are five types of callouts: note, tip, warning, caution, and important. As with lots of Quarto things they are specified using a division, like so:

::: {.callout-note}
This is a note callout.
:::

The different callouts come with appropriate colours by default, which you can change in the theme. You can also have collapsible callouts by adding the collapse=true option, where true will have the callout collapsed by default. You can also specify titles in the same way using the title=<TITLE> option or by adding the title directly to the callout content, like so:

::: {.callout-note}
## This is the callout title

This is a note callout.
:::

You can change the overall appearance of callouts by using the appearance option or the callout-appearance global option. Valid values are default, simple and minimal, with decreasing usage of colours and weights. You can also suppress the callout icons using icon=false or callout-icon: false in a similar manner.

6.3 Mixing R and Python

Earlier in the tutorial we showed how to change the language using the engine global option, but there is actually a way to use both R and Python in the same Quarto document. This is done via the Knitr engine and the reticulate R package, which allows communication between any variables and data you store in either R or Python code chunks. While this may not be that common of a use-case, it’s still great that it’s there for those that want access to it. We won’t go through the details of how this works here, but you’re welcome to go and check out the official reticulate website for yourself.

If you just want to mix R and Python in a single Quarto document without the interoperability between the languages it’s a lot simpler, though. You can either just install the reticulate package (r-reticulate in Conda) or add the python.reticulate=FALSE chunk option to the Python chunks.

6.4 Citations

You can actually write whole articles in Quarto! For that purpose, it’s also great that you can cite things from a bibliography as well. Specifying the bibliography file(s) is done using the bibliography global option; specifying the citation style can be done using a csl (Citation Style Language) file and the csl global option. Citation itself is similar to cross-referencing (@cross-ref), but is surrounded by square brackets: [@citation]. You can read more details about citations at the Quarto website.