2  Positron and Quarto: A Unified Multi-Language Workflow

Positron is the next-generation data science IDE introduced by Posit (formerly RStudio) to supersede the RStudio IDE. This shift reflects Posit’s broader strategy to support multiple programming languages (notably R and Python) under one roof. In parallel, Quarto has emerged as a language-agnostic successor to R Markdown (RMD). Quarto is an open-source scientific and technical publishing system that unifies and extends the functionality of the R Markdown ecosystem, adding native support for multiple languages like Python and Julia in addition to R. Together, Positron and Quarto provide an integrated environment for reproducible research, combining code, results, and prose across languages in a single workflow.

Quarto is a stand-alone command-line tool (not an R package) that Positron bundles and supports out-of-the-box. Positron’s integration ensures that users can create, edit, and render Quarto documents seamlessly without manual installation of Quarto or its dependencies. This chapter will explore how to work with Positron and Quarto, updating terminology and technical details from the RStudio/R Markdown era to the new Positron/Quarto ecosystem. We will examine Quarto’s document structure, demonstrate multi-language code chunks execution, discuss Positron’s R and Python integration (including the Python console and environment management), and highlight best practices for reproducible analysis in this modern environment. The academic tone and instructional clarity are maintained throughout, with references provided in APA style to relevant documentation and sources.

2.1 From RStudio and R Markdown to Positron and Quarto

Positron vs. RStudio: Positron retains the familiar feel of RStudio but is built as an extensible, polyglot IDE on the Visual Studio Code framework. RStudio was historically centered on R, featuring a single R console and tools tightly coupled to the R language. In contrast, Positron was designed from the ground up to handle multiple languages, especially R and Python, with first-class support for each. It provides a more integrated experience for multi-language workflows than RStudio did. Long-standing limitations of using Python in RStudio (which relied on relatively ad-hoc solutions like the reticulate package) are resolved by Positron’s native support for Python, including robust code completion, syntax highlighting, and debugging tools for both languages side by side. Posit’s decision to rebrand and develop Positron underscores a strategic move to a cross-language platform, acknowledging the reality that modern data science often mixes R with Python and other tools. Positron is built on open-source VS Code, which means it inherits extensibility and familiarity (e.g. command palette, integrated terminal, source control features) while offering a tailored interface for data science needs.

Quarto vs. R Markdown: Quarto builds upon the concepts of R Markdown, unifying various extensions (rmarkdown, bookdown, xaringan, etc.) into one consistent system. Like R Markdown, Quarto allows users to intermix narrative text with code and results in a single document for transparent, reproducible analysis. However, Quarto is explicitly language-agnostic: whereas R Markdown documents (.Rmd) are executed within an R session (with optional Python via reticulate), Quarto documents (.qmd) natively support multiple programming languages and can execute in different computational engines. In fact, Quarto was designed to be a standalone tool (installed separately from R) that can run with or without R. As Wickham et al. note, Quarto reflects “everything learned from expanding and supporting the R Markdown ecosystem over a decade,” including built-in support for Python and Julia and a more uniform syntax for extensions. This means that many features that required additional packages in R Markdown are built into Quarto (for example, publishing websites or presentations, managing citations, etc., all use Quarto’s unified CLI and configuration). Quarto uses Pandoc under the hood for document conversion, just as R Markdown did, but the rendering process is now orchestrated by the Quarto CLI instead of the R rmarkdown package. In RStudio, one would “Knit” an R Markdown; in Positron, one “Renders” or “Previews” a Quarto document – effectively the same concept of executing code and generating output, but via Quarto’s system.

Notably, R Markdown’s core syntax carries over into Quarto with some improvements. Quarto still uses Markdown for prose and fenced code blocks for code, but it standardizes the way code cell options are specified. For instance, Quarto encourages using YAML options within chunks (preceded by #| in the code) for clarity. This new syntax replaces some of the old knitr chunk option notation. An example of a Quarto code chunk in an R context is:


::: {.cell}
::: {.cell-output-display}
![](chapter2_files/figure-html/fig-cars-1.png){#fig-cars width=100%}
:::
:::

Here, the chunk is labeled and the code is hidden from the output, using #| lines inside the chunk. Quarto still recognizes the older chunk option format (e.g., `{r echo=FALSE}), but the YAML-style options improve readability and consistency across languages. We will see more on multi-language chunk syntax in subsequent sections.

In summary, Quarto generalizes R Markdown’s literate programming paradigm beyond R, and Positron provides the development environment to leverage that paradigm smoothly with multiple languages. This chapter assumes familiarity with the basic idea of combining narrative and code, and now focuses on how this is achieved in Positron with Quarto.

2.2 Quarto Document Structure and Syntax

A Quarto document (.qmd file) has a structure very similar to an R Markdown document, consisting of: (1) an optional YAML header, (2) code chunks in various languages, and (3) narrative text in markdown format:contentReferenceoaicite:15. The YAML header, enclosed by --- lines at the top of the file, contains metadata such as the title, author, date, and output format(s). For example:

---
title: "My Analysis"
author: "Jane Doe"
date: 2025-07-08
format: html
---

This metadata block declares that the document should be rendered to an HTML format (additional formats like PDF or Word can be listed here as well). Quarto’s YAML fields are largely compatible with those of R Markdown but also include Quarto-specific options (for instance, a Quarto project can be defined with a _quarto.yml file for global options, and Quarto can specify multiple output formats or use profiles for different rendering configurations).

Following the YAML, the body of the document consists of markdown text interwoven with code chunks. Code chunks in Quarto are delineated by triple backticks and curly braces containing the language name. For example, an R chunk starts with {r} and a Python chunk with {python}. Quarto supports many languages (R, Python, Julia, JavaScript/Observable, Bash, etc.), making it truly language-agnostic. Inline code can also be embedded in text (as in R Markdown) using the syntax appropriate to the engine. In an R-enabled document, one can insert an inline R expression with 4 to dynamically print results in the text. Quarto also supports inline computations with other languages; for instance, if using the Jupyter execution engine with Python, one could use Jinja2-like expressions { } in text for Python, though in most cases it’s simplest to use R inline or restructure the document such that outputs from other languages are shown in chunks rather than inline.

Code chunk options: Quarto adopts a unified syntax for chunk options that works across languages. Options are specified as YAML key-value pairs either in the chunk header or (preferably) as commented lines inside the chunk. Each #| line within a chunk sets an option. Common options include echo (whether to display source code), include (whether to include the results in the output), fig-cap for figure captions, and so on. For example, in an R chunk one might write #| echo: false to hide the code, or in a Python chunk #| warning: false to suppress warnings. This syntax is consistent across R, Python, Julia, etc., making the document format easier to read and write, especially in multi-language contexts. Quarto’s documentation provides extensive details on available options and their usage. The key takeaway is that Quarto’s document format is a superset of R Markdown’s: anything you could do in R Markdown, you can do in Quarto, but Quarto adds more flexibility for other languages and a more streamlined syntax for configuration.

Execution engines: When you render a Quarto document, Quarto automatically chooses an execution engine depending on the content of the file. By default, Quarto uses the knitr engine (R) if it finds R code chunks, and uses Jupyter engines for other languages. A .qmd file that contains only R code will be processed with knitr (just like an R Markdown document), whereas a file that contains only Python chunks will by default use a Jupyter Python kernel. If a Quarto document mixes R and Python chunks, the default behavior is to use the R knitr engine to execute all chunks, running Python code via the reticulate package. Reticulate (Allaire, Ushey, & Tang, 2018) is an R package that serves as an interface to Python, allowing R to start a Python session, execute Python code, and exchange data between R and Python seamlessly. Quarto leverages reticulate in this scenario so that all code runs in a single R process – this means R and Python variables can be shared (with some limitations) during the render. For example, using reticulate, an R chunk could create a dataframe and a subsequent Python chunk could access that dataframe via the r object (reticulate’s mechanism to import R objects into Python), and vice versa for bringing Python objects into R. This unified execution via R is convenient for cross-language interaction in a single document. However, Quarto also gives you the option to force a different engine: you can explicitly request the Jupyter engine or the knitr engine in your Quarto document YAML (using execute: engine: jupyter or engine: knitr) if needed. For instance, advanced users might choose the Jupyter engine for a mixed-language document, which would spawn separate kernel processes for each language (one for R and one for Python). In that case, R and Python would not share state, but it might be desirable for other reasons (e.g., using a specific Python environment or replicating a Jupyter Notebook environment). In general, the default engine choices suffice for most use cases; the ability to handle multiple languages is largely automatic and behind-the-scenes.

2.3 Interactive Multi-Language Development in Positron

One of the strengths of using Positron (as opposed to a plain text editor or older RStudio versions) is its rich support for interactive execution of multi-language Quarto documents. Positron integrates the Quarto Visual Studio Code extension, which provides commands and keyboard shortcuts to run cells (code chunks) and even individual lines of code within a chunk. This works similarly to the RStudio notebook mode, but now for multiple languages.

Running code chunks: In Positron’s source editor, each Quarto code chunk has a “Run” button (a play icon) at the top, and you can also execute a chunk using a keyboard shortcut (e.g., Ctrl+Shift+Enter, analogous to RStudio’s shortcut). When you run a chunk, Positron will automatically send the code to the appropriate interpreter session. Positron is designed to manage multiple interpreter sessions concurrently (R and Python, potentially even multiple of each). At any given time, one interpreter is considered the active session, which determines the default context for code execution and IDE features. If you execute an R chunk and the active session is an R interpreter, the code runs there; if the active session is Python, Positron will detect the mismatch and look for an R session. According to the interpreter management rules, Positron will use the most recently created R session, or start a new one if necessary, to execute the R chunk. The same logic applies for Python chunks: if a Python chunk is executed while the active interpreter is R, Positron will find or start a Python session to run that chunk. This dynamic switching happens behind the scenes, ensuring that each language’s code executes in an appropriate environment.

The result is a fluid interactive experience: you can step through a Quarto document chunk by chunk, even if chunks are in different languages, and see results immediately. For example, if you have an R chunk followed by a Python chunk, running them in sequence will produce output in the R console for the first and in the Python console for the second. Positron’s console pane clearly indicates which interpreter is active and even highlights it in the interpreter picker UI, so you always know whether you are looking at R output or Python output. Any graphics produced by R code will appear in the Plots/Viewer pane (just like in RStudio), and graphics from Python (e.g., matplotlib plots) will appear in the equivalent plots pane when the Python session is active. Figure 1 illustrates this: the middle pane shows a Quarto document with Python code, the rightmost pane is the active Python console with variables and plot output, and the left pane lists files and Quarto assistant – demonstrating how Python code execution results integrate into the IDE’s panels just as R results do.

(Figure 1: Positron running a Quarto document with mixed R and Python chunks. The Python chunk’s output (including a plot) is shown in the Python console and plots pane, thanks to the Quarto extension’s integration with Positron’s native interpreters.)

By default, Positron shows output in the console and plot panes, rather than inline in the editor. This is a design choice aligned with many users’ preferences from RStudio (where one could choose to show output in console rather than inline). If you prefer notebook-style interleaved output (where results appear immediately below the code in the editor), Quarto’s VS Code extension (and thus Positron) currently does not duplicate Jupyter’s inline display for every scenario; instead, you rely on the IDE panes for output. This may change as the tools evolve, but it’s important to note the distinction: rendering the entire document will produce a finished output (e.g., an HTML file) with all figures and tables in place, whereas interactive running of chunks in the IDE is mainly for development and analysis purposes, showing you results live but not altering the source document. You can always render a preview to see the full integrated result.

The Positron Console and Terminal: Positron provides both a Console pane (for language interpreters) and a Terminal pane (for command-line shell access). The Console pane hosts the interactive R and Python sessions. You can have multiple consoles running simultaneously – for example, an R console for data analysis and a Python console for a machine learning model – and switch between them via the interpreter picker menu. Each console is an independent session with its own workspace and variables. Positron’s interface shows the name of each interpreter (e.g., “R 4.2.3” or “Python 3.11 venv:myenv”) so you can distinguish them. Standard features like command history, object completion, and help lookups work in each console (for R, it uses R’s internal help; for Python, it may use IPython if available for rich repr and help).

The Terminal pane is a separate feature that gives you access to an OS shell (bash, PowerShell, etc.), similar to RStudio’s Terminal tab. This is useful for environment management tasks or version control. For instance, you might use the Terminal to run git commands or to install Python packages via pip/conda if needed. Because Positron is based on VS Code, you can open multiple terminals as well. While not a primary focus of this chapter, it’s worth noting that having an integrated terminal means you don’t have to leave the IDE to perform system-level tasks – reinforcing reproducibility and convenience (e.g., you can document in Quarto and execute a shell script to download data, all within one project interface).

2.4 R and Python Integration in Positron

Positron’s ability to work with R and Python side by side is a major advancement for bilingual data science teams. Here we detail how Positron manages these integrations under the hood and how you as a user can control and optimize them.

Multiple interpreter sessions: Unlike the classic RStudio IDE which allowed only one R session per window (and only experimental support for a single “other” language via reticulate), Positron can host multiple concurrent sessions for R and Python. This design enables workflows that span multiple environments and languages, all in one workspace. For example, you could have one R session with R 4.3 for general analysis, another R session with an older version of R to run legacy code, and a Python session using a specific conda environment for deep learning – all open and easily switchable in one Positron window. The Interpreter Picker (located at the top-right of the Positron window) is the control center for these sessions. The active interpreter is indicated there, and by clicking the picker you can select any running session or start a new one. When creating a new interpreter session, you will be prompted to choose from the available interpreters on your system (e.g., a list of discovered R installations or Python environments). This flexibility is particularly useful in Quarto documents that use more than one language, as Positron ensures each chunk uses the correct engine without manual intervention.

Python integration and reticulate: In Positron, Python integration is no longer an afterthought; it is built-in. You can start a Python session simply by selecting a Python interpreter from the picker or by running a Python snippet in a Quarto document (Positron will auto-start a Python session if one isn’t already active). Under the hood, if you render a Quarto document that mixes R and Python, Quarto (via knitr) will use reticulate to execute Python code within the R process. However, interactively, Positron runs Python code in a real Python process (separate from R). This means that when working line-by-line, your R and Python variables are not automatically shared as they would be in a single reticulate-driven knit. For instance, if you assign a dataset to df in an R chunk and then run a Python chunk that tries to access df directly, it will fail in interactive mode because the Python session knows nothing of R’s objects. To share data between R and Python interactively, you would have to explicitly transfer it (for example, using reticulate’s r object in a Python chunk during render, or writing data to a file/CSV/RDS and reading in Python, etc.). Recognizing this distinction is important for development: you might choose to develop mainly in one language at a time when stepping through code, and rely on Quarto’s unified execution (with reticulate) when doing the final render so that cross-language references resolve. Alternatively, if cross-language interactivity is needed, one could force Quarto to always use reticulate even in preview mode by starting an R session and using quarto preview from R – though typically, the Positron UI handles preview by calling the Quarto CLI directly.

In practice, many Quarto documents use one primary language (say R) and occasionally call out to another (say Python for a specific machine learning library). A recommended pattern is to do as much as possible in one session and only use the second language in self-contained chunks that don’t need to share state beyond input/output files or final results. If deeper integration is needed (e.g., manipulating an R data frame in Python and returning it), reticulate offers R functions like py$object or py_run_string to fetch or create Python objects in R, and vice versa. But such usage can complicate the reproducibility, so clear documentation in your Quarto report is advised whenever you bridge languages.

Language-specific features in Positron: Each interpreter in Positron brings language-specific tools. For R, Positron provides the usual features like the Environment pane (listing R objects), the Plots pane, the Help pane for R documentation, and support for R’s interactive graphics (e.g., manipulating a plotly graph). For Python, Positron includes analogous features: a Variables pane that can show Python variables (including data frames, NumPy arrays, etc.), a Plots pane for Python graphics, and integration with Jupyter-like completions and introspection. For instance, when using Python, pressing Tab for auto-completion will leverage the Python language server or runtime introspection to list attributes, and writing help(func) or func? (if IPython is running) can display documentation in the console. Positron’s Data Explorer is another tool that works with both R and Python objects to let you inspect data frames or tables in a spreadsheet-like view (similar to the View() function in R). In short, Positron aims to give Python in the IDE a treatment equal to R, which is a significant improvement over the RStudio era.

2.5 Python Terminal Access and Environment Management

Working with multiple languages means managing multiple package ecosystems and interpreter installations. Positron, and the Quarto ecosystem more broadly, embrace best practices for environment management to ensure reproducibility.

Python environments: Positron automatically discovers Python installations and virtual environments on your system. It supports common environment managers including venv (Python’s built-in virtual environments), Conda (conda or mamba environments), Python version managers like pyenv, and others. When you open Positron, it will scan standard locations for environments, such as any .venv/ or .conda/ folders in your project directory, known global locations (like ~/.local/share/virtualenvs or Conda’s env directories), and the system PATH for global Python installs. These are then listed in the interpreter picker. Positron prefers that you use a project-specific virtual environment rather than a system Python, in line with Python community recommendations to avoid dependency conflicts. For example, if your Positron project folder contains a .venv directory, Positron will list that environment at the top of the interpreter choices for Python. You can easily create a new environment from within Positron: the Command Palette has a command “Python: Create Environment” which will walk you through selecting an environment type (venv, Conda, etc.) and automatically set it up in your project. This environment will then be activated for the Python console. Managing packages in that environment (installing libraries like pandas or numpy) can be done either through the Terminal (e.g., pip install pandas while the environment is active) or using Conda’s tools if it’s a Conda env. Because the environment is specific to the project, your Quarto document executions will be reproducible – you could even share the environment definition (such as a requirements.txt or environment.yml for Conda, or use Python’s pip freeze to record package versions).

Quarto itself does not enforce any particular Python environment, but it will use whatever Python Positron (or your system) points to. If you run quarto render on the command line, Quarto will look for a Python interpreter to execute Python chunks. By default on many systems it uses python3 on the PATH, so if you have a specific environment, you should activate or specify it before rendering. One convenient way to manage this in an R-centered project is to use the renv R package’s Python integration. The renv package (from Posit) can be used to manage R dependencies, and it also has functions like renv::use_python() which will automatically create and link a Python virtual environment to your R project. This ensures that when someone else (or you in the future) opens the project, both R and Python package versions are locked and can be restored. In an APA style reference, we cite renv’s documentation as (Ushey, 2021) if needed, but here we just note that renv is a tool for R that can help manage Python deps as well.

R environments and versions: Positron supports multiple R installations on the same system. It will discover all R versions above 4.2.0 (the minimum supported) by searching standard install directories on each OS, such as /Library/Frameworks/R.framework/Versions on macOS or C:\\Program Files\\R\\ on Windows. If you have multiple R versions, these will be listed in the interpreter picker (e.g., “R 4.3.1”, “R 4.2.3”). While R doesn’t use virtual environments in the same sense as Python, one can manage R package libraries on a per-project basis using renv. We strongly recommend using renv for any serious project: it creates an renv.lock file capturing exact package versions, which is crucial for reproducibility. When you load a project (with an renv infrastructure) in Positron, it will typically ask if you want to restore the project library, ensuring the R packages are as recorded. In combination with Quarto, this means that your R code chunks will run with the expected package versions. Positron does not automatically create renv projects, but it works seamlessly with them.

Additionally, Positron works with rig, an R installation manager on macOS and Linux that allows side-by-side R versions (Csárdi, 2022). The Positron docs mention that only “orthogonal” R installations are supported on macOS (meaning each R version has its own R framework folder, as rig sets up, rather than one symlinked framework). This is a technical detail, but in essence, if you’re managing multiple R versions, a tool like rig is recommended to avoid conflicts, and Positron will recognize those installations.

Ensuring reproducibility: Whether using R or Python, a key best practice is to document your computational environment. For R, this may include recording the R version and using a lockfile (renv or packrat) for packages; for Python, it may include an environment.yml (for conda) or requirements.txt (for pip) or a pyproject/Pipfile if using those systems. Quarto projects can also include a requirements.txt that Quarto will use to automatically install needed Python packages if you render on, say, Posit’s publishing platform (Posit Connect). The bottom line is that Positron and Quarto give you the tools to manage environments, but it’s up to the user to use them wisely. Within Positron, once you’ve selected a specific R interpreter and a specific Python environment, that selection is retained for the project (recorded likely in project settings or the .Rproj file that Positron still uses for project metadata). Make sure to instruct collaborators to use the same interpreters, or provide them with instructions to install the same versions. The chapter’s original guidance on reproducibility – e.g., avoiding setting a working directory manually, not relying on the GUI state, and using project-oriented workflows – all still apply. Quarto even allows you to set an explicit execution working directory for all code (via the YAML option execute: dir: ...) to ensure consistency.

2.6 Rendering and Publishing with Quarto in Positron

Writing and running chunks interactively is only part of the workflow; ultimately, you will render your Quarto document to produce a final output (HTML, PDF, slides, etc.). In Positron, rendering is integrated via the Quarto extension. You can render the document by invoking the Quarto: Preview command, which will execute quarto render behind the scenes and show the resulting output in the Viewer pane. The “Render” or “Preview” button in the Positron toolbar (usually appearing in the top-right of the source editor when a .qmd is open) triggers this as well. By default, Preview will build the document in the format specified in the YAML (e.g., HTML). You can also preview other formats through Quarto: Preview Format, selecting, say, PDF or Word if those are listed as output options in the YAML. The preview appears alongside your source in a pane within Positron, allowing you to see the fully rendered result (with formatted text, figures, tables, etc.) as you work. If you prefer an external preview (for instance, opening in a web browser), Positron allows that as well, but the internal preview is very convenient for quick iteration.

One useful feature is Render on Save: you can configure Positron to automatically re-render the Quarto document every time you save it. This behaves somewhat like RStudio’s Visual Markdown editor or like live preview in R Markdown notebooks. It’s turned off by default (because rendering can be time-consuming for long documents), but you can enable it either globally in settings or per document by adding editor: render-on-save: true to the YAML. When enabled, each Ctrl+S (save) will trigger a render, updating the preview. This can be a great feedback loop for catching errors early or seeing how your latest code change affects the output.

The process of rendering a Quarto document in Positron is essentially the same two-step that R Markdown used: first, execute all code and create an intermediate Markdown file; second, call Pandoc to produce the final output. If any errors occur during rendering (e.g., an R error in a chunk, or a missing library in Python), Quarto will halt and report the error in the Positron console. A common source of confusion can be Python configuration – if Quarto (running via the CLI) cannot find the correct Python, you may get errors about Python not found (or the wrong version). Since Positron bundles Quarto, it generally knows about the Python you are using in the IDE, but in some cases (especially on Windows), you might need to ensure that the Python interpreter is correctly set in your PATH or use Quarto’s virtual-env execution options. The Stack Overflow post by ErikOnSoftware (2024) describes an issue where Quarto in Positron couldn’t locate python3.12.exe until the environment was properly configured. The solution in such cases is to either install the expected Python version or configure Quarto (via quarto.ini or environment variables) to point to the right Python executable.

Once rendered, you can use the output for its intended purpose: an HTML report to share, a PDF for a paper or presentation slides for a talk. Quarto’s outputs are as varied as R Markdown’s were, and more – including interactive dashboards, blog websites, books, and so on. Positron fully supports Quarto’s advanced use cases; for example, you can work on a Quarto Website or Book project in Positron and use the same editor and preview to render the entire site or book (Positron will call quarto preview which will render all pages and serve a preview site locally).

Publishing Quarto documents is also straightforward. If you were used to using RStudio Connect (now Posit Connect) or RPubs for R Markdown, the analogous tool for Quarto is Posit Connect – Quarto output can be published to Connect with one click if configured, or you can publish to other services (Quarto has support for GitHub Pages, Netlify, etc., often just by rendering to the right folder). Since this chapter is focused on authoring, we won’t delve into publishing details, but it’s worth noting that the reproducibility of your document (ensured by proper environment management and Quarto’s deterministic execution) makes it much easier to reliably publish or share the analysis. In an APA-style citation context, one might reference the Posit Connect documentation for Quarto (Posit, 2025) to see how deployment works, but from the author’s perspective, nothing in your document needs to change to publish – it’s about where you render it.

2.7 Best Practices in the Positron-Quarto Ecosystem

To conclude the chapter, we highlight some best practices and conceptual points, updated for Positron and Quarto:

  • Reproducibility and Project Orientation: Use Positron Projects (via .Rproj files) to organize your work. Even though it is no longer just “R” in the project, the project file helps Positron remember settings like which interpreters you used and where your working directory is. Keep your Quarto documents and any supporting scripts in a project directory. Manage R packages with renv and document your Python environment requirements. Avoid using the global workspace or manual saving of R data objects (.RData files); instead, all code needed to produce results should be in your Quarto document or scripts (this was a key rule in R Markdown workflows and remains crucial). Quarto documents are knit from scratch each time you render, so they enforce the rule that your code must run from a clean state – this is good for catching hidden dependencies. Positron facilitates this by allowing you to restart interpreter sessions easily (there is a “Restart” command for both R and Python consoles) to test running from a blank slate. Use that to your advantage during development.

  • Quarto Document Structure: Keep the document focused and well-structured. Use section headings (as we have done in this chapter) to organize content. Quarto (like R Markdown) supports all the standard Markdown headings, lists, and tables, as well as cross-references for figures/tables and citations for references. Because Quarto is static by nature (it runs all code then generates output), avoid overly interactive setups in the document (if you need interactivity, consider Shiny for R or voila for Python, which Quarto can embed, but that’s beyond scope). Instead, think of the Quarto document as a reproducible paper or report. This mindset, as championed by Knight et al. (2020) in literate programming literature, improves clarity and reproducibility.

  • Code Chunk Management: Use chunk labels (with the label: option) for all chunks that produce figures or important results, so you can reference them (e.g., using @fig-cars in text to refer to a figure by its label). This also helps with navigating the document – Positron’s document outline can show chunk labels to jump around. For long computations, consider Quarto’s caching options (similar to knitr cache) to speed up iterative rendering – Quarto can cache results of chunks so that not every render re-runs expensive code, if configured. However, be mindful that caching adds complexity (you must manually reset cache when needed), so only use it when necessary.

  • Multi-language Considerations: If using both R and Python in one analysis, decide how to divide tasks. Often, users will do data wrangling and visualization in one language and something like modeling in another. If you need to pass data between R and Python, the reticulate approach on render is the easiest (e.g., use reticulate::py_save_object() and py_load_object() for larger data, or share via R objects in reticulate). Alternatively, break the analysis: use one Quarto document for R parts, another for Python parts, and combine results if that simplifies environment issues. Quarto lets you compose documents together in a project (like an R Markdown book or website), so one chapter could be R, another Python. This modular approach can make each document’s execution engine simple (one language each) and avoid cross-language state sharing issues. Regardless, document clearly in text when a context switch happens (e.g., “Next, we use Python (via scikit-learn) to build a model…”). This ensures readers and collaborators know what to expect.

  • Use of Positron Tools: Leverage Positron’s Assistant and other bundled extensions. Positron has a built-in “Positron Assistant” which can help with tasks like writing code (it’s an AI code assistant) and may integrate with documentation lookup. It also includes a Connections pane for database connections (works for R’s DBI or Python’s SQL connectors similarly). If your chapter originally advised using RStudio’s addins or add-on packages, check Positron’s Extensions marketplace. Many RStudio addins (like the datapasta or styler) might now be VS Code extensions or built-in features. For example, Positron includes the Quarto extension as we saw, and also a Jupyter extension for working with Jupyter notebooks directly. If you prefer a notebook interface, Positron even allows opening a .ipynb file with a Notebook Editor that is rendered with Quarto behind the scenes. This gives you a Jupyter-like experience but tied into the Quarto system (so you can later convert the notebook to a Quarto document if desired). In summary, be open to using these new tools – they can enhance productivity, but they may require a bit of learning if you’re coming from pure RStudio. The Positron documentation and community forums (Posit Community) are great resources for questions during this transition.

2.8 Conclusion

Positron and Quarto represent a modern, flexible approach to reproducible data science, carrying forward the spirit of RStudio and R Markdown but extending it to a multi-language world. In this chapter, we replaced references to RStudio with Positron and R Markdown with Quarto, reflecting the evolving landscape. We updated technical details to highlight how Positron natively handles R and Python integration – from concurrent interpreter sessions and multi-language chunk execution to an integrated Python console and robust environment management tools – and how Quarto provides a language-agnostic document format that unifies decades of lessons from the R Markdown ecosystem.

Researchers and analysts can now seamlessly mix R and Python in a single document, use whichever language is best suited to each task, and still produce a cohesive report or publication. The Positron IDE supports this workflow by providing a familiar yet enhanced interface, where code completion, debugging, and visualization work across languages without awkward workarounds. Meanwhile, Quarto ensures that the final product – be it a journal article, a business report, or a tutorial – is reproducible and shareable, with support for multiple output formats and embedding of multi-language results.

The transition from RStudio/R Markdown to Positron/Quarto does come with some learning curve, especially in terms of new syntax (e.g., Quarto’s chunk options) and new mental models (e.g., thinking in terms of multiple sessions). However, the core principles of literate programming and reproducible research remain the same. By adopting Positron and Quarto, you are investing in a future-proof workflow that aligns with the trend of polyglot data science. Posit (2024) emphasizes that Positron is the future of their development environment, built to handle the needs of a world where R is just one of many tools. Likewise, Quarto’s emergence signals a commitment to open-source, interoperable, and cross-language communication of data science results.

In summary, Positron and Quarto together provide a powerful, cohesive ecosystem for modern data analysis and documentation. We encourage readers to explore Positron’s official guides and Quarto’s comprehensive documentation for further details on specific features (such as authoring slides, creating websites, or advanced Python integration scenarios). By following the best practices outlined and leveraging the capabilities described in this chapter, you can ensure that your analyses are not only technically correct, but also elegantly presented and easily reproducible by others – whether they choose to run your code in R, Python, or any other supported language. This alignment with reproducibility standards and cross-language collaboration is what makes the Positron-Quarto ecosystem a robust choice for academic and professional data science projects in the years to come.

References