Python to R: A Quick Reference
You already know how to program. This page maps the Python patterns you used in GEOL1151 to their R equivalents. Keep it open during the first few weeks.
The big picture
| Python (GEOL1151) | R (this course) | |
|---|---|---|
| Data container | NumPy array (data[:,0]) |
Data frame (df$column) |
| Plotting | matplotlib (plt.plot()) |
ggplot2 (ggplot() + geom_...()) |
| File I/O | np.loadtxt(), pd.read_excel() |
read.csv() |
| Stats | np.mean(), np.std() |
mean(), sd(), t.test(), aov() |
| Environment | Jupyter notebooks | Quarto Live (WebR in browser) |
The single biggest change: in Python you worked mostly with arrays (grids of numbers). In R you’ll work mostly with data frames (tables where each column has a name and can be a different type).
Variables and assignment
# Python
x = 42
name = "Durham"# R
x <- 42
name <- "Durham"R uses <- for assignment. = also works but <- is the convention.
Vectors (like 1D arrays)
# Python
import numpy as np
temps = np.array([15.2, 16.1, 14.8, 17.3])
temps.mean() # 15.85
temps[0] # 15.2 (0-indexed)
temps[1:3] # array([16.1, 14.8])# R
temps <- c(15.2, 16.1, 14.8, 17.3)
mean(temps) # 15.85
temps[1] # 15.2 (1-indexed!)
temps[2:3] # 16.1 14.8Watch out: R is 1-indexed. The first element is [1], not [0].
Loading data
# Python — NumPy (whitespace-delimited)
data = np.loadtxt("rocks.dat", skiprows=1)
# Python — Pandas (CSV or Excel)
import pandas as pd
df = pd.read_csv("data.csv")
df = pd.read_excel("data.xlsx")# R — CSV
df <- read.csv("data.csv")
# First few rows
head(df)
# Column names
names(df)
# Dimensions
nrow(df)
ncol(df)Accessing columns
# Python — NumPy array
data[:, 0] # First column (by position)
# Python — Pandas DataFrame
df["temperature"] # By name
df.temperature # Also by name (dot notation)# R — data frame
df$temperature # By name (most common)
df[, 1] # By position
df[, "temperature"] # By name (bracket notation)The $ operator is your main tool for getting at columns.
Filtering rows
# Python — NumPy
hot = data[data[:, 2] > 30, :]
# Python — Pandas
hot = df[df["temperature"] > 30]# R — base
hot <- df[df$temperature > 30, ]
# R — dplyr (from Week 2 onward)
library(dplyr)
hot <- df |> filter(temperature > 30)Note the comma in df[rows, ] — R needs it to distinguish row selection from column selection.
Creating new columns
# Python — Pandas
df["density"] = df["mass"] / df["volume"]# R — base
df$density <- df$mass / df$volume
# R — dplyr
df <- df |> mutate(density = mass / volume)Summary statistics
# Python
np.mean(data[:, 0])
np.median(data[:, 0])
np.std(data[:, 0])
np.min(data[:, 0])
np.max(data[:, 0])
len(data)# R
mean(df$temperature)
median(df$temperature)
sd(df$temperature)
min(df$temperature)
max(df$temperature)
nrow(df)
# All at once
summary(df$temperature)Note: R’s sd() uses n−1 (sample SD) by default. NumPy’s np.std() uses n (population SD) by default. For the same result as R, you’d need np.std(x, ddof=1) in Python.
Plotting
Quick base R plots (Week 1)
# Python — matplotlib
plt.plot(data[:, 0], data[:, 4])
plt.xlabel("Year")
plt.ylabel("Flow rate")
plt.title("River Wear")# R — base graphics
plot(df$year, df$flow,
xlab = "Year",
ylab = "Flow rate",
main = "River Wear")Histograms
plt.hist(density, bins=20)hist(df$density, breaks = 20)ggplot2 (from Week 2)
ggplot2 takes a different approach from matplotlib. Instead of calling separate functions for each element, you build a plot by adding layers:
library(ggplot2)
ggplot(df, aes(x = year, y = flow)) +
geom_line()
ggplot(df, aes(x = density)) +
geom_histogram(bins = 20)
ggplot(df, aes(x = formation, y = temperature)) +
geom_boxplot()The pattern is always: ggplot(data, aes(...)) sets up the mapping, then geom_...() draws the geometry. You’ll find this more systematic than building plots one plt. call at a time.
Functions
# Python
def celsius_to_kelvin(temp):
return temp + 273.15# R
celsius_to_kelvin <- function(temp) {
temp + 273.15
}R returns the last expression in a function automatically — no return needed (though return() exists if you want it).
Loops and conditionals
# Python
for year in range(2000, 2025):
if year % 4 == 0:
print(year, "is a leap year")# R
for (year in 2000:2024) {
if (year %% 4 == 0) {
cat(year, "is a leap year\n")
}
}You’ll rarely need explicit loops in R — most operations work on whole vectors at once. For example, mean(df$temperature) averages all values without a loop.
The pipe: |>
R has a pipe operator that chains operations left to right:
# Without pipe
summary(subset(df, year > 2010))
# With pipe
df |>
subset(year > 2010) |>
summary()Read |> as “then”. It passes the result of the left side as the first argument to the right side. You’ll use this heavily from Week 2.
Things that will trip you up
| Gotcha | Python | R |
|---|---|---|
| Indexing starts at | 0 | 1 |
| Assignment | = |
<- |
| Exponentiation | ** |
^ |
| Integer division | // |
%/% |
| Modulo | % |
%% |
| Boolean AND/OR | and / or |
& / | (vectorised) |
| Not equal | != |
!= (same) |
print() |
print() or just type the name |
|
| NULL/None | None |
NULL |
| Missing values | NaN / None |
NA |
| Check missing | pd.isna() / np.isnan() |
is.na() |
| String quotes | 'single' or "double" |
"double" preferred |
| Comments | # |
# (same) |
Getting help
# R — help on a function
?mean
help(mean)
# Search help
??histogramIn Python you used help(np.mean) or np.mean? in Jupyter. Same idea, different syntax.