Will teach you the fundamentals of working in R by walking through a ‘typical’ bioinformatics workflow.
We will work slowly and there will be repetition. You will build good habits through experience.
At the end of this course you will grasp the fundamentals and be in a good position to work with google, llms, supervisors and colleagues to solve specific problems and challenges.
Workshop aims
Chapter 2 “Whole game”
We will:
Introduce Positron as an IDE for code writing and to help manage all our files.
Import data into Positron.
Clean and tidy the data.
Visualise the data for ourselves.
Carry out “data wrangling” (getting the data into the shapes and formats we need).
Visualise the data for presentation.
Objectives for the course
Learn how to use Positron and Workspaces to keep work organised.
Learn the fundamentals of the R programming language: functions, objects and packages.
Develop the habit of writing readable, reproducible code.
Be able to interpret errors and warnings.
Understand the format of data in R.
Use the dplyr functions for data preparation and processing (“wrangling”).
Be able to create basic visualisations of your data.
On the topic of LLMS
We do not know where LLMs will be in five years.
We can not anticipate the price of tokens in the future.
Currently, LLMs are very capable of writing code.
Code is usually good, though not excellent.
Knowledge of coding remains valuable for:
Interpreting code
Phrasing questions and workflows
Learning new workflows/interfaces is a skill.
“Loss of ownership” is a very real problem.
The R programming language
Created in 1993 by Dr. Ross Ihaka and Dr. Robert Gentleman at the University of Auckland, Aotearoa New Zealand.
Widely used in statistics and biological sciences.
Free, flexible, supported by the community.
Base R was used to build packages that accomplish specific tasks.
Base R packages includes a mix of styles and formats.
Challenging to learn!
The tidyverse dialect
A series of packages designed from the ground up to work together.
Uses a consistent and logical style with a shared format.
Human readable, intuitive, easy to learn.
Highly popular, well documented, many resources available.
Help and Viewer panes (for HTML output and websites)
Editor Area (top center)
Your main window for code development
Should be a Quarto doc
Tabs are great
Split the editor into columns for additional files
Panel Area (bottom center)
Console (R or Python), Terminal and Output tabs
Console output could be hidden with inline Quarto outputs
optional, embed a nice Terminal tab
Secondary Side Bar (right)
Variables, display loaded objects and their str()
Session, manage and switch R/Python interpreters
History of past commands
database Connections interface
Plots pane for graphics output
Reproducibility
Code must be reproducible over the complete process.
Global environments should not be saved
Rendering Quarto files (.qmd) solves this issue
Caution
Jupyter Notebooks cache intermediate results and require more attention.
Positron’s default is already reproducible
Unlike RStudio, Positron does not save or restore your .RData workspace by default, and never prompts you about it.
No dialogue to disable
There is nothing to switch off: sessions always start from a clean environment unless you explicitly save one yourself.
Other settings of note
Base pipe with Ctrl+Shift+M (Windows/Linux) or Shift+Cmd+M (Mac)
Inserts |> by default. Switch to %>% via the positron.r.pipe setting (Gear icon > Settings, search “Pipe”).
Code diagnostics
Toggle live diagnostics with the positron.r.diagnostics.enable setting.
Not as granular as RStudio (yet)
Positron currently offers a single on/off switch rather than RStudio’s fine-grained checklist. Third-party linters such as lintr are not yet integrated into the language server.
Positron workspaces
Workspaces and git repos
Here we introduce you to two separate, but related, topics: workspaces and git repos.
A workspace is a folder that stores everything relating to the project. Positron has a system for managing this process.
A repo (short for “repository”) is an online version of the project, containing most but not all files (no raw data for privacy reasons, no intermediate data if it can be easily recomputed).
We want the workspace (local) and repo (online) to be linked, so that our changes are stored and versioned.
In this section we will introduce workspaces and repos, and you will set up a workspace and repo. We will write code in the workspace, and you will gain experience in keeping the linked repo up to date.
The workspace-oriented approach
Any coding, including testing, you conduct should happen in the context of a workspace.
A workspace in Positron is a folder — there is no required project file (no .Rproj needed).
The folder you open is the reference for all paths in your project (the working directory).
A good project name goes a long way.
Make it unique!
There are multiple ways to start a workspace
Positron’s New Folder wizard (from a template)
Open an already existing folder
Clone (checkout) an existing repository
Git repositories
Git is a system for code versioning, usually with a remote repository (options exist: github and gitlab).
We can create a repository (repo) via the online interface as a starting point.
Repos can be public or private.
Repos are cloned onto a local computer.
Disclaimer: I personally start all my projects with a github repo.
Must choose a proper title
Prompted to create a description
This pre-work effort is valuable
Creating and cloning a repo
Create a new repo
Clone a new repo
Cloning a repo from Positron
Create a new repo
Open the Command Palette: (Ctrl+Shift+P on Windows/Linux, Shift+Cmd+P on Mac)
Clone a new repo
It’s your turn!
Create a new github repo with the name “r_intro_day_1”.
Give this repo a description, select add README, and choose a license (GNU General Public v3.0).
Under “Code”, select SSH and copy the url.
If you did not correctly set up your SSH key, you can use HTTPS, but this is not a secure way to work going forward.
In Positron, open the command palette (Cmd + Shift + P for Mac, Ctrl + Shift + P for Windows), type “Clone” and select the drop-down option.
You should now see your repo name on the left-hand side under Explorer.
Creating a workspace
Open the Command Palette (Ctrl+Shift+P on Windows/Linux, Shift+Cmd+P on Mac) and run Workspaces: New Folder from Template
Pick the R Project (or Python Project) template
Name the folder properly
Choose whether to initialize git and a package environment (renv)
No .Rproj file
Positron folders are plain directories: opening the folder is opening the project. If you still have an old .Rproj file lying around, Positron happily ignores it — see the migration notes.
Initialization from scratch
Good practice
Use git when starting projects from scratch, either through the wizard’s checkbox or afterwards from the Source Control view in the Activity Bar.
Starting from scratch means:
Create an empty folder
Open it in Positron (File > Open Folder…)
Initialize git and add sub-folders as you go
Working directory set up
Avoid using setwd() and absolute file paths
What’s wrong with setwd()?1
setwd() set the working directory to a specific folder through an absolute file path
We will write and run code directly from the quarto document we just opened (with Cmd / Cntrl + ShiftP, “New Quarto”).
We store all code in “chunks”. To add a chunk, put the cursor in the document (below the pairs of dashes). Then use Cmd + Shift + I (mac)
To run a code chunk, place the cursor anywhere on one of the lines you want to run and use Cmd + Return (mac) or Cntrl + Enter (windows).
Code chunks cont
We should see the code and the output appear in the console.
This is how we work in R: write code in a document, run the code, output is either displayed on the screen or saved as files.
It’s your turn!
Buttons are slow - use shortcuts!
Use either Cmd + Shift + i (Mac) or Ctrl + Alt + i (Windows) to add a new code chunk.
In the new chunk write:
6+6
[1] 12
4*12
[1] 48
Click anywhere on the line that says 6 + 6 and use command + return (Mac) or Ctrl + enter to run the code.
Save the file so that this code can be accessed later.
Committing our work to the repo I unsaved and uncommitted files
Committing our work to the repo II stage and message
Write a commit message.
Select files to stage via the +.
Once files are committed, they need to ‘synced’ or ‘pushed’ to the remote repo.
The bioinformatician’s workflow
Almost any project will include the following steps:
Import data
Exploratory analysis
Data wrangling
Visualisations and other outputs
Importing data
R is primarily used for handling ‘flat’ data: rows and columns.
The most common type of flat data file is the CSV (comma separated values).
Typically, the first row will contain column names and is referred to as the “header”. Rows underneath the header contain data for each column, with columns separated by commas.
The csv format
Importing data: setting up
First, store the data within a /data subdirectory.
Second, install and load packages for importing data.
It’s your turn!
Exercise: storing data
Go to https://tinyurl.com/penguinData2025. Use the download button to get a local copy of the file.
In your intro_to_r project directory, create a subdirectory called data.
Copy/move the penguin_dataset.csv file to the new data directory.
Then:
Open a new quarto document with the title “Intro to R Day 1”.
Save it as day_1.qmd
Type “## Setup” (this should appear as a heading).
Type “### Packages”
Packages
Packages are collections of additional data or functions that extend the R language.
We can equate packages with apps.
To use a package requires two steps:
Install the package from a remote repository (one-time only)
Load the package into Positron (every session)
Hex stickers
It’s your turn!
Install and load the tidyverse
Create a code block in your quarto doc, add the code below, and execute:
Install packages - run this the first time you work with a new package.
install.packages("tidyverse")
Load packages - run this every time you work with the package.
We just saw the head() function. head() and tail() print the first, or last, six rows of the object.
head(penguins, 4)
# A tibble: 4 × 8
species island bill_len bill_dep flipper_len body_mass sex year
<chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <dbl>
1 Adelie Torgersen 39.1 18.7 181 3750 male 2007
2 Adelie Torgersen 39.5 17.4 186 3800 female 2007
3 Adelie Torgersen 40.3 18 195 3250 female 2007
4 Adelie Torgersen NA NA NA NA <NA> 2007
Functions can be modified with arguments.
Most functions have defaults which are not shown. Be aware of function defaults!
The pipe
This works best if you read “|>” as “and then…”
penguins |># Start with the penguin data AND THENna.omit() |># Remove the NAs AND THENarrange(bill_len) |># Arrange (sort) the rows AND THENhead() # Keep just the head (top 6 rows)
Are numerical values normally distributed? Are there outliers? Do we have batch effects?
Exploring the penguins dataset
Use the glimpse() function to look at the penguins dataset.
What are the data types of each column? Which are categorical, which are numeric?
Use the count() function on one of the categorical variables.
Beyond numbers and words
“Far better an approximate answer to the right question, which is often vague, than an exact answer to the wrong question…”
- John Tukey
“The simple graph has brought more information to the data analyst’s mind than any other device. It specializes in providing indications of unexpected phenomena”.
- John Tukey
Data visualisation with ggplot
ggplot (“Grammar of Graphics”): work iteratively, build complexity.
Focus on the format.
Demonstrates a key loop in data analysis: visualise your data, make adjustments, transform the data and visualise again.
The ggplot format
The ggplot format has three parts:
Calling the ggplot function and specifying the data.
Mapping the data: what data is displayed on the x and y axis.
Plotting the data with a geom function - there are different geoms for different types of plots.
Note that the geom is a new function, which means we need to add a “+” to the previous line.
Using ggplot and mapping variables to colour, identify which of the categorical variables in penguins best explains the sub-grouping we observe in bill depth vs length.
Hints:
glimpse() and summary() are useful functions for looking at your data.
Even if you have found a variable that looks like it explains your data, did you check whether other variables also look like they explain the data?
Hypothesis: You cannot imagine a plot that can’t be made with ggplot
Challenge: I challenge you to clearly describe a plot or visualization that cannot be created in ggplot. There is a prize available.
Conditions:
You must be able to describe this clearly, to the point where we as a group all agree on what you are requesting.
This must be a plausible static visualization (i.e., no 3-dimensional, sound-producing scifi graph).
You must give us your description by the start of Day 2 at the latest, and you must give us your description as soon as you come up with it.
No LLMs.
If, by the end of our final day, I haven’t been able to build OR find a plot that represents data as per your description, you win.