R & AI (& Testing)

RaukR 2026 • Data Science With R

Sebastian DiLorenzo

18-Aug-2026

What this sessions will cover


  • A brief history of Posit data science agents
  • Provider setup
  • AI types
  • Posit Assistant modes
  • Some useful commands
  • Prompt engineering 101
  • Some LLM specific packages in R
  • Testing, a toy example






A brief history of Posit data science agents

Positron Assistant

June 2025 (Preview)

A general-purpose coding assistant built into Positron. Aware of the live R/Python session state, it helped write, edit, and debug code — with agent mode for code execution. User needed their own model provider to use it.

Databot

August 2025

A exploratory data analysis agent for Positron. Unlike traditional code assistants, Databot connected directly to active R/Python sessions to inspect variables, data frames, plots, and console history in real time. User needed their own model provider to use it.

Posit Assistant

April 2026 (Preview feature) / July 2026 (General availability)

Combines the strengths of both predecessors into a full-spectrum data science agent. Runs in Positron and RStudio, powered by the Posit AI model service or other model provider. Features skills, plan mode, reasoning, and live session awareness.

Provider setup

  • Enabled by default in positron since July, 2026.
  • Enable in settings.json using assistant.enabled: true
  • Enable model providers in Configure Language Model Providers.

AI types

Ask

You type a question, the model answers. No memory of previous messages, no back-and-forth. Like a search engine that understands natural language.

Use when: You need a quick explanation, definition, or one-off answer.

Chat

A conversation. The model remembers what was said earlier in the session and can refine answers based on follow-up questions.

Use when: You need to iterate, clarify, or build on previous answers — e.g. debugging a problem step by step.

Agentic

The model doesn’t just answer — it acts. It can write and execute code, read files, call tools, and loop through steps autonomously to complete a goal.

Use when: You want the LLM to carry out a multi-step task, not just describe how to do it.

Posit Assistant modes

Mode Purpose
Normal Default mode — safe operations auto-approved, risky ones prompt for confirmation
Plan (/plan) Read-only exploration and planning before any code changes are made
Auto (/auto) A classifier reviews tool calls before they run, blocking actions outside the task scope
Cleaning (/clean) Guided data audit and cleaning, with every judgment call routed to the user for approval

Sandbox (/sandbox): OS-level isolation for bash commands — restricts filesystem writes to the workspace, blocks network access, and protects sensitive paths like ~/.ssh. Off by default.

Some useful commands

Command What it does
/report Turns your conversation into a tidy Quarto document you can save and share
/notebook Exports the conversation as a Jupyter notebook
/savememory Saves information about your project so the assistant remembers it next time
/compact Squishes the conversation history to save space when it gets too long
/clear Starts a fresh conversation (keeps your current model settings)
/yolo Lets the assistant do everything without asking for your OK each time
/restricted Makes the assistant ask for your approval before doing anything

Prompt engineering 101




  • Be specific and clear about what you want
  • Avoid ambiguity
  • Give examples
  • Break down complex tasks into smaller steps
  • Follow best coding practices

“Create an image depicting a maestro directing a handful of robots that are building a machine. The maestro should have a blueprint rather than musical notes. The style should be realistic cartoonish, with a white background so it works well to insert on a white slide.”

Prompt engineering 101



Bad prompt

“Fix my RNA-seq code”



Good prompt

“I have a data frame counts with genes as rows and samples as columns. Write an R function using DESeq2 to run differential expression between two groups defined by a condition column in coldata. Return a results table sorted by adjusted p-value. Follow tidyverse style conventions.”

Some LLM specific packages in R

ellmer — Chat with LLMs from R. Supports providers such as OpenAI, Anthropic, Google Gemini, and Ollama. Handles tool calling, streaming, and structured data extraction.

shinychat — Add a chat UI component to Shiny apps. Provides a ready-made chat interface that integrates with ellmer or any streaming LLM backend.

kuzco — Computer vision for R. Describe, classify, and extract structured information from images using multimodal LLMs.

Lots of other LLM adjacent packages, a pretty updated list: https://luisdva.github.io/llmsr-book/r-pkgs.html

Testing

Where: Your R package.


Writing tests might feel like extra work, but it pays off quickly:

  • Fewer bugs — Tests catch mistakes early, before they silently corrupt results downstream.
  • Better code structure — Testable code tends to be modular and well-defined; writing tests often reveals design problems.


Informal testing

Running code interactively to check that it does what you expect — printing outputs, inspecting objects, trying edge cases in the console. Fast and intuitive, but not repeatable: you have to re-run it manually every time something changes.


Automated testing

Storing tests as code so they can be re-run at any time. If you change a function and a test breaks, you know immediately. This makes refactoring safer and collaboration easier.

Automated testing

Setup

usethis::use_testthat()
  1. Creates tests/testthat/
  2. Adds testthat to Suggests in DESCRIPTION
  3. Creates tests/testthat.R.

Create a test

usethis::use_test("foobar")

Creates and opens tests/testthat/test-foobar.R.

Run tests

Command What it does
testthat::test_file("tests/testthat/test-foobar.R") Run a single test file
devtools::test() Run all tests in tests/testthat/
devtools::check() Run all tests + full package check

Tip

Best is to use the Testing activity bar!

Parts of a test

R/foobar.R:

foobar <- function(x) {
  if (!is.numeric(x)) {
    stop("Input must be numeric")
  }
  x + 1
}

tests/testthat/test-foobar.R:

test_that("numeric values work", {
  expect_equal(foobar(2), 3)
  expect_equal(foobar(-2), -1)
})
test_that("non-numeric input throws an error", {
  expect_error(foobar("a"), "must be numeric")
})

Expectations

Function Brief Description
expect_equal() Equality with numeric tolerance
expect_identical() Exact identity (strict type check)
expect_true() Check if expression is TRUE
expect_false() Check if expression is FALSE
expect_match() Match character string against a regex
expect_type() Check underlying type of object
expect_error() Check if code throws an error
expect_message() Check if code produces a message
expect_warning() Check if code produces a warning
  • A test file holds one or more test_that() tests.
  • Each test describes what it’s testing: e.g. “multiplication works”.
  • Each test has one or more expectations: e.g. expect_equal(2 * 2, 4).

Lab exercises

Start from the libminer package you created yesterday. If you need you can fork and use Jennys.

Use Posit Assistant, PA, to:

  1. Ask which tests PA thinks are appropriate for your function. Don’t make edits.
    • Which mode did you use?
    • Do you agree with its suggestions?
  2. Make and execute a /plan to add tests for your function. Try to prompt engineer the tests you want.
    • Did you get the output you expected or did you need to make some edits?
  3. Save your progress so far in a /report. Afterwards /clear the conversation. Rule of thumb; /clear whenever you think it is a new conversation.
  4. Pick an appropriate mode and create a new function for your package.
    • Then add all the other necessary pieces such as documentation, tests, new dependencies etc for your function.
    • At this point, do your tests pass? Does devtools::check() pass?
  5. BONUS: Open a new workspace and create a quarto presentation. You can pick the subject to populate the slides with.
    • Can you add appropriate images to the slides? Did it work like you expected?
  6. BONUS: Find a messy dataset and import it into R. Try to use /cleaning mode to clean it.

Thank you!

Questions?

2026 • SciLifeLabNBISRaukR