Demo!

Using AI to translate code between R and Python

Step 1: A shared dataset

We’ll use a small made-up dataset: hours studied vs. exam score for 12 students defined in both R and Python.

Many of us have seen these parallels: c() becomes [], data.frame() becomes pd.DataFrame(), and head() becomes .head().

Step 2: Fit a linear model in R

In R, fitting a linear model and getting a full statistical summary takes just two lines:

Step 3: From R to Python: ask the AI

Suppose you’ve never written Python before, but you need to reproduce this analysis. Let’s ask an AI assistant for help.

Prompt: β€œTranslate this R code to Python”

πŸ§‘ Prompt

Translate this R code to Python:

model <- lm(score ~ hours, data = study_data)
summary(model)

πŸ€– AI response

In Python, the closest equivalent is scikit-learn’s LinearRegression. Here’s the translation:

from sklearn.linear_model import LinearRegression

X = study_data[["hours"]]
y = study_data["score"]

model = LinearRegression()
model.fit(X, y)

print("Intercept:", model.intercept_)
print("Coefficient:", model.coef_[0])

Try running the translated code below (the first run may take a few seconds while scikit-learn loads):

Better prompts: β€œTake me step by step through the differences and similarities in this code”

The first translation works, but a better prompt can help us actually understand what changed.

πŸ§‘ Prompt

I'm a stats student fluent in R.
Translate this R code to Python using sklearn, AND:

1. Add inline comments mapping each R line to its Python equivalent.
2. Flag any idiom differences (e.g., formula interface vs. design matrix).
3. End with one concept-check question I should be able to answer
   before I move on.
4. Make sure to tell me which packages have to be loaded and how to load them.

model <- lm(score ~ hours, data = study_data)
summary(model)

πŸ€– AI response

Here’s the same translation, broken into pieces. Click through each tab:

R: base only, no imports needed

lm() and summary() ship with base R.

Python: install and import

pip install scikit-learn numpy pandas
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score

R original

model <- lm(score ~ hours, data = study_data)
summary(model)

Python (sklearn): annotated

# ── R: model <- lm(score ~ hours, data = study_data) ──────────────────
# R uses a formula interface: 'score ~ hours' is a symbolic expression.
# sklearn has NO formula interface. You must build X and y manually.

X = study_data[['hours']]   # double brackets β†’ 2-D DataFrame (nΓ—1)
                             # R adds intercept automatically; sklearn does too (fit_intercept=True default)
y = study_data['score']     # single bracket β†’ 1-D Series

model = LinearRegression()  # equivalent to specifying lm(), no fitting yet
model.fit(X, y)             # <- this is where lm() actually does its work

# ── R: summary(model) ─────────────────────────────────────────────────
# R's summary() prints coefs, SEs, t-stats, p-values, F-stat, RΒ² in one call.
# sklearn gives NONE of that directly. It is a prediction library, not inference.
# You reconstruct the pieces manually:

print("Intercept :", model.intercept_)     # R: coef(model)[1]
print("Coefficient:", model.coef_[0])      # R: coef(model)['hours']
print("RΒ²         :", model.score(X, y))   # R: summary(model)$r.squared

# ⚠ p-values, SEs, and t-stats are NOT available in sklearn.
# Use statsmodels.formula.api.ols() if you need full inference output.

Formula interface vs. design matrix. R’s score ~ hours is declarative: R parses variable names, builds the design matrix, and adds an intercept for you. sklearn is imperative: you construct X as an explicit 2-D array and y as a 1-D array before fitting. If you accidentally pass a 1-D array as X, sklearn raises a ValueError.

Inference vs. prediction focus. R’s lm() is built for statistical inference: standard errors, t-tests, F-tests are first-class output. sklearn’s LinearRegression is optimised for predictive accuracy; it deliberately omits p-values. For inference in Python, use statsmodels.formula.api.ols(), which also supports the formula syntax.

Attribute naming. R stores results as a named list (model$coefficients). sklearn stores them as object attributes with trailing underscores: model.coef_ and model.intercept_. The trailing underscore is a sklearn convention signalling β€œset after fitting.”

  • The statsmodels alternative is often the right call for real statistics. statsmodels.formula.api.ols('score ~ hours', data=study_data).fit() accepts R-style formula syntax and produces a summary() that looks almost identical to R’s. Use sklearn when doing prediction and cross-validation, not inference.

  • fit_intercept=True default. sklearn includes an intercept by default (same as R’s lm()). If you manually dummy-code all levels of a categorical variable and pass them in, you’ll get perfect multicollinearity, the same trap as forgetting to drop a reference level in R with -1 in your formula.

  • model.score(X, y) gives RΒ², not adjusted RΒ². R’s summary() reports both. If you need adjusted RΒ², compute it manually from n, p, and the raw RΒ².

When you write X = study_data[['hours']] with double brackets instead of study_data['hours'] with single brackets, what is the difference in shape, and why does model.fit() require that specific shape?

Step 4: Match the syntax!

Test what you just learned. For each R snippet, choose its Python equivalent.

R Python
x <- 5
c(1, 2, 3)
data.frame(a = x, b = y)
study_data$hours
lm(y ~ x, data = df)
nrow(df)

Step 5: Your turn: fill in the blanks

Now let’s try a different task on a different dataset: the correlation between temperature and ice cream sales.

Here’s the complete R version:

Now write the equivalent Python. Fill in the blanks below and run it!