Python-to-R Translation Skill

SkillAI & models

Python-to-R translation for data analysis. Maps Python (polars, plotnine, pyfixest, statsmodels, svy, geopandas) to R (tidyverse, ggplot2, fixest, survey, sf). Use when user has Python background or requests Python-equivalent code comments in R pipelines.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Python-to-R Translation Skill skill

What this skill tells your AI

The instructions your AI receives, as published by daaf-contribution-community/daaf in .claude/skills/python-r-translation/SKILL.md and read by ahel’s review.

Python-to-R translation reference for quantitative social science data analysis. Maps Python ecosystem packages (polars, plotnine, pyfixest, statsmodels, linearmodels, svy, geopandas, scikit-learn) to R equivalents (tidyverse/dplyr, ggplot2, fixest, base R stats, plm, lme4, survey, sf, terra, tidymodels). Use when user mentions Python background, requests Python-equivalent code comments in R pipelines, needs to understand R analysis code from a Python perspective, or wants to translate Python data analysis concepts to R. Covers paradigm differences, verb-by-verb operation translations, regression modeling, causal inference, visualization, and workflow adaptation.

Cross-language translation reference for researchers moving between the Python and R data analysis ecosystems. This skill maps Python packages, idioms, and workflows to their DAAF R equivalents so that Python-background users can audit, understand, and learn from DAAF-produced R code, and so that code-producing agents can annotate their output with Python equivalents when directed.

This skill is a routing hub -- it provides overview tables, decision trees, and directs readers to the detailed reference files listed below. The reference files contain the exhaustive verb-by-verb mappings, code examples, and edge-case documentation.

What This Skill Does

  • Maps the Python data analysis ecosystem to DAAF's R stack across data wrangling, modeling, visualization, causal inference, surveys, spatial analysis, and workflow tooling
  • Provides a structured annotation protocol for agents to add inline Python-equivalent comments to R code
  • Identifies paradigm gaps where Python and R diverge fundamentally, so users know where to expect friction

Use cases:

  1. Python user auditing DAAF R code and needing to understand what operations are being performed
  2. Agent annotating R code with Python-equivalent comments for a Python-background researcher
  3. Python user learning R for data analysis and needing a conceptual bridge
  4. Translating a specific R operation or idiom to its Python equivalent
  5. Understanding where Python tools have no direct R equivalent (and what the workaround is)

How to Use This Skill

Reference File Structure

Each topic in ./references/ contains focused documentation:

FilePurposeWhen to Read
paradigm-differences.mdCore language and paradigm differencesEncountering fundamental R-vs-Python confusion
dplyr-polars.mdCore dplyr/tidyr verbs explained for polars users (filter, mutate, joins, reshaping, window functions, piping)Reading or writing data manipulation code
strings-dates-factors.mdString, date/time, and factor operations (stringr, lubridate, forcats for polars users)Working with string/date/categorical columns
regression-modeling.mdfixest/stats/plm explained for pyfixest/statsmodels/linearmodels usersReading or writing regression code
visualization.mdggplot2/plotly R explained for plotnine/plotly Python usersReading or writing visualization code
causal-inference.mdR causal inference ecosystem explained for Python usersWorking with DiD, RDD, IV, event studies
survey-spatial-ml.mdsurvey/sf/tidymodels explained for svy/geopandas/scikit-learn usersWorking with surveys, spatial data, or ML
workflow-environment.mdDAAF/R workflow explained for Python-background usersAdapting to DAAF's R execution model
external-resources.mdCurated guides and tutorials with provenanceSeeking additional learning materials
gotchas.mdCommon Python-user mistakes in RDebugging or reviewing code from Python perspective

Reading Order

  1. Python user auditing DAAF R code: paradigm-differences.md then the relevant domain file (e.g., dplyr-polars.md for data wrangling, regression-modeling.md for models) then gotchas.md
  2. Agent annotating R code with Python equivalents: Agent Code Annotation Protocol section below, then the relevant domain file for the code being annotated
  3. Learning R from Python background: paradigm-differences.md then dplyr-polars.md then workflow-environment.md then external-resources.md
  4. Looking up a specific translation: Quick Decision Trees below, then the relevant reference file

Quick Decision Trees

"What does this R code do in Python terms?"

What kind of R operation?
|-- Data wrangling (filter, mutate, join, pivot, summarise)
|   +-- ./references/dplyr-polars.md
|-- Regression / statistical modeling
|   +-- ./references/regression-modeling.md
|-- Plotting / visualization
|   +-- ./references/visualization.md
|-- Causal inference (DiD, RDD, IV, event studies)
|   +-- ./references/causal-inference.md
|-- Surveys / spatial / machine learning
|   +-- ./references/survey-spatial-ml.md
+-- Fundamental language differences (types, syntax, environment)
    +-- ./references/paradigm-differences.md

"Why does this R code look different from Python?"

What looks unfamiliar?
|-- Pipe operator (|>)
|   +-- ./references/paradigm-differences.md
|-- Formula interface (y ~ x1 + x2)
|   +-- ./references/regression-modeling.md
|-- Unquoted column names in functions
|   +-- ./references/paradigm-differences.md
|-- library() loads everything
|   +-- ./references/gotchas.md
|-- factor() and levels
|   +-- ./references/paradigm-differences.md
|-- <- for assignment
|   +-- ./references/gotchas.md
+-- Interactive console / RStudio workflow
    +-- ./references/workflow-environment.md

"What R package replaces my Python package?"

Which Python package?
|-- polars --> dplyr + tidyr + data.table
|   +-- ./references/dplyr-polars.md
|-- plotnine --> ggplot2
|   +-- ./references/visualization.md
|-- plotly (Python) --> plotly (R)
|   +-- ./references/visualization.md
|-- pyfixest --> fixest
|   +-- ./references/regression-modeling.md
|-- statsmodels (OLS, GLM) --> base R stats (lm, glm) + lmtest + sandwich
|   +-- ./references/regression-modeling.md
|-- linearmodels (panel, IV) --> plm + estimatr
|   +-- ./references/regression-modeling.md
|-- statsmodels MixedLM --> lme4 (lmer)
|   +-- ./references/regression-modeling.md
|-- svy --> survey (Lumley)
|   +-- ./references/survey-spatial-ml.md
|-- geopandas --> sf + terra
|   +-- ./references/survey-spatial-ml.md
|-- scikit-learn --> tidymodels / caret
|   +-- ./references/survey-spatial-ml.md
|-- marginaleffects (Python) --> marginaleffects (R)
|   +-- ./references/regression-modeling.md
|-- rdrobust (Python) --> rdrobust (R)
|   +-- ./references/causal-inference.md
+-- marimo --> Quarto / RMarkdown
    +-- ./references/workflow-environment.md

"Something isn't working and I think it's a Python habit"

What went wrong?
|-- Used = instead of <- for assignment
|   +-- ./references/gotchas.md
|-- 0-indexed access gave wrong element
|   +-- ./references/gotchas.md
|-- Used True/False instead of TRUE/FALSE
|   +-- ./references/gotchas.md
|-- Missing value handling surprised me (NA vs None/NaN)
|   +-- ./references/paradigm-differences.md
|-- import vs library() confusion
|   +-- ./references/gotchas.md
|-- Expected method chaining, got pipe errors
|   +-- ./references/paradigm-differences.md
+-- Model output structure is different
    +-- ./references/regression-modeling.md

Package Mapping Overview

R PackagePython EquivalentFidelityKey Difference
dplyr + tidyrpolarsLowVerb grammar vs expression system; pipe vs method chaining
fixestpyfixestHighNear-identical formula syntax; minor SE default differences
ggplot2plotnineHighSame grammar of graphics; bare names vs string quoting for aes
plotly (R)plotly (Python)Highplot_ly() vs px.scatter(); similar output
base R stats + lmtest + sandwichstatsmodelsMediumSingle formula syntax vs three Python dialects
plm + estimatrlinearmodelsMediumpdata.frame vs pandas MultiIndex for panel structure
lme4statsmodels MixedLMMedium(1 | group) in formula vs separate groups=/re_formula= arguments
tidymodels / caretscikit-learnMediumDeclarative recipe pipeline vs imperative fit/predict
sf + terrageopandasMediumst_*() functions vs GeoDataFrame methods; different CRS handling
survey (Lumley)svyMediumFull GLM family coverage vs limited (gaussian/binomial/Poisson/gamma)
Quarto / RMarkdownmarimoMediumKnit-based linear execution vs reactive cells

Fidelity key: High = near-direct translation, same mental model. Medium = same capability, different API patterns. Low = fundamentally different paradigm requiring conceptual remapping.

Library Versions

Translations in this skill reference specific library versions. R versions reference CRAN releases as of March 2026 (R 4.5.3). Python versions are pinned in DAAF's Docker environment (Python 3.12). When syntax or behavior has changed between versions, the reference files note the change.

R PackageR Version (CRAN)Python EquivalentDAAF Version
dplyr + tidyr + data.tabledplyr 1.2.0, tidyr 1.3.2, data.table 1.18.2polars1.39.3
fixest0.14.0pyfixest0.60.0
ggplot24.0.2plotnine0.15.3
plotly (R)4.12.0plotly6.5.2
base R stats + lmtest + sandwichlmtest 0.9-40, sandwich 3.1-1statsmodels0.14.6
plm + estimatrplm 2.6-7, estimatr 1.0.6linearmodels7.0
lme42.0-1statsmodels MixedLM0.14.6
tidymodels / carettidymodels 1.4.1, caret 7.0-1scikit-learn1.8.0
sf + terrasf 1.1-0, terra 1.9-11geopandas1.1.3
surveysurvey 4.5svy0.19.0
marginaleffects (R)0.32.0marginaleffects0.5.0
rdrobust (R)3.0.0rdrobust1.3.0
Quarto / RMarkdownQuarto 1.7.29marimo0.19.11

Pinning note: linearmodels, marginaleffects, and rdrobust are version-pinned in DAAF's Dockerfile (linearmodels==7.0, marginaleffects==0.5.0, rdrobust==1.3.0) and pre-installed alongside the rest of the Python stack. Translations reference their documented APIs as of March 2026.

Top 10 Paradigm Differences

These are the friction points Python users encounter most frequently when reading or writing DAAF R code. Each is covered in depth in the referenced file.

#Friction PointPython WayR WayReference
1Pipe operatordf.filter(...).with_columns(...)`df> filter(...)
2Unquoted column namespl.col("x") string referencesx bare name in dplyr verbsparadigm-differences.md
3Missing valuesNone, NaN, and null (context-dependent)Single unified NA typeparadigm-differences.md
4Formula interfaceThree incompatible Python dialectsOne universal ~ syntax everywhereregression-modeling.md
5Assignment operator= for assignment<- for assignment (= also works but unconventional)gotchas.md
6Package loadingimport pkg as alias (explicit namespace)library(pkg) exports all namesparadigm-differences.md
7Factor / categoricalpl.Categorical (storage only)factor() with ordered levels, auto-dummies in modelsparadigm-differences.md
80-indexed vs 1-indexedx[0] is first elementx[1] is first elementgotchas.md
9Boolean valuesTrue / FalseTRUE / FALSEgotchas.md
10Data frame boundaryMust call .to_pandas() for modelingSame tibble flows everywhere: wrangle, model, plotparadigm-differences.md

Agent Code Annotation Protocol

This section defines when and how code-producing agents add inline Python-equivalent comments to DAAF R scripts.

When to Annotate

Annotations are added only when the orchestrator explicitly passes a Python-background directive to the agent. This is not a default behavior.

Trigger conditions (orchestrator activates this when any apply):

  • User states they have a Python background
  • User requests Python-equivalent comments in R code
  • User asks to understand R code from a Python perspective

How the orchestrator passes the directive: The orchestrator adds the following to the agent prompt:

"User has Python background. Load python-r-translation skill. Add inline Python-equivalent comments for non-trivial data operations."

Comment Format

# Python: df.filter(pl.col("year") == 2020)
filtered <- df |> filter(year == 2020)

# Python: df.with_columns((pl.col("count") / pl.col("count").sum()).alias("pct"))
result <- df |>
  mutate(pct = count / sum(count))

# Python: pf.feols("y ~ x1 + x2 | state + year", data=pdf, vcov={"CRV1": "state"})
fit <- feols(y ~ x1 + x2 | state + year, data = df, vcov = ~state)

What to Annotate

  • Annotate: Data wrangling (dplyr/tidyr operations), modeling calls (fixest, lm, glm, plm), visualization layer construction (ggplot2, plotly), causal inference method calls
  • Do NOT annotate: library() calls, cat()/stopifnot() validation lines, file I/O boilerplate (read_parquet, write_parquet), config sections, section separator comments

Rules

  • One # Python: comment per logical operation, placed on the line immediately above the R code
  • Keep annotations to a single line; abbreviate complex Python pipelines if needed
  • Python annotations are in addition to standard IAT comments (# INTENT:, # REASONING:, # ASSUMES:), not a replacement
  • Consumer agents: research-executor, code-reviewer, debugger, data-ingest

Related Skills

SkillRelationship
tidyverseR-side data wrangling -- detailed API reference for the polars equivalent
fixestR-side fixed effects regression -- detailed API for the pyfixest equivalent
ggplot2R-side static visualization -- detailed API for the plotnine equivalent
plotly-rR-side interactive visualization -- detailed API for plotly Python equivalent
r-statsR-side general modeling -- covers base R stats, lmtest, sandwich equivalents
plmR-side panel/IV models -- covers linearmodels equivalents
survey-rR-side survey analysis -- covers svy (Python) equivalents
sf-terraR-side spatial data -- covers geopandas equivalents
tidymodelsR-side ML -- covers scikit-learn equivalents
quartoR-side notebooks -- covers marimo workflow equivalents
r-python-translationParallel skill for R-background users reading Python code -- same domain, reverse direction
stata-python-translationParallel skill for Stata-background users -- shares the same Python target stack

Note: Individual tool skills contain library-specific usage guidance (syntax, gotchas, performance). This skill provides the Python-to-R conceptual bridge -- use both together when a Python-background user is working with a specific R library.

ML interpretation/fairness asymmetry (honest signal): Python's ML interpretation and fairness ecosystem is genuinely deeper (SHAP, fairlearn, and related tooling). The R-side equivalents (iml, DALEX, kernelshap, fairmodels) are installed and covered by the tidymodels skill's interpretation.md and fairness.md, so real R workflows exist for these tasks -- but for ML-heavy interpretation or fairness translation questions the Python direction carries more depth, and translating to R may surface a residual ecosystem gap rather than a one-to-one mapping.

Topic Index

TopicReference File
Pipe operator (`>`) and method chaining
Unquoted column names (non-standard evaluation)./references/paradigm-differences.md
Missing value semantics (NA vs None/NaN/null)./references/paradigm-differences.md
Type system differences./references/paradigm-differences.md
Package/namespace model (library vs import)./references/paradigm-differences.md
1-indexing vs 0-indexing./references/paradigm-differences.md
Data frame philosophy (tibble everywhere vs polars-pandas boundary)./references/paradigm-differences.md
Copy-on-modify vs reference semantics./references/paradigm-differences.md
dplyr verb mapping (filter, select, mutate, arrange)./references/dplyr-polars.md
summarise / group_by equivalents./references/dplyr-polars.md
tidyr verbs (pivot_longer, pivot_wider, separate, unite)./references/dplyr-polars.md
Join operations (left_join, inner_join, anti_join)./references/dplyr-polars.md
across() / where() equivalents./references/dplyr-polars.md
case_when equivalent./references/dplyr-polars.md
Window functions (over vs group_by + mutate)./references/dplyr-polars.md
Pipe chaining comparison./references/dplyr-polars.md
Lazy evaluation (scan_parquet vs arrow)./references/dplyr-polars.md
nest/unnest equivalents./references/dplyr-polars.md
readr I/O equivalents./references/dplyr-polars.md
String operations (stringr vs polars .str)./references/strings-dates-factors.md
Date operations (lubridate vs polars .dt)./references/strings-dates-factors.md
Factor/categorical operations (forcats vs polars Categorical)./references/strings-dates-factors.md
data.table vs polars./references/strings-dates-factors.md
fixest formula syntax in pyfixest./references/regression-modeling.md
lm() / glm() in statsmodels./references/regression-modeling.md
Formula interface comparison (R universal vs three Python dialects)./references/regression-modeling.md
Standard error specification differences./references/regression-modeling.md
plm panel models in linearmodels./references/regression-modeling.md
lme4 mixed effects equivalents./references/regression-modeling.md
marginaleffects (R to Python)./references/regression-modeling.md
Model summary / tidy output./references/regression-modeling.md
Sandwich / robust SE equivalents./references/regression-modeling.md
ggplot2 layer mapping to plotnine./references/visualization.md
aes() bare names vs string quoting./references/visualization.md
Theme customization./references/visualization.md
Scale functions./references/visualization.md
Faceting (facet_wrap, facet_grid)./references/visualization.md
plotly R vs plotly Python./references/visualization.md
ggsave equivalent./references/visualization.md
Coefficient and effect plots./references/visualization.md
Difference-in-differences (sunab, did2s)./references/causal-inference.md
Regression discontinuity (rdrobust)./references/causal-inference.md
Instrumental variables (feols IV vs pyfixest/linearmodels)./references/causal-inference.md
Event study designs./references/causal-inference.md
Synthetic control./references/causal-inference.md
Matching / propensity scores./references/causal-inference.md
Staggered DiD estimators./references/causal-inference.md
survey package to svy./references/survey-spatial-ml.md
svydesign / svymean / svyglm equivalents./references/survey-spatial-ml.md
sf spatial operations to geopandas./references/survey-spatial-ml.md
CRS / projection handling./references/survey-spatial-ml.md
Spatial joins (st_join vs sjoin)./references/survey-spatial-ml.md
tidymodels pipeline to scikit-learn./references/survey-spatial-ml.md
BRR / jackknife replication weights./references/survey-spatial-ml.md
Raster data handling (terra vs rasterio)./references/survey-spatial-ml.md
Feature engineering (recipes vs sklearn Pipeline)./references/survey-spatial-ml.md
Cross-validation (rsample vs sklearn)./references/survey-spatial-ml.md
RStudio vs DAAF workflow./references/workflow-environment.md
Quarto / RMarkdown vs marimo./references/workflow-environment.md
File-first execution model./references/workflow-environment.md
Package management (renv vs Docker)./references/workflow-environment.md
Project structure conventions./references/workflow-environment.md
Curated Python-to-R migration guides./references/external-resources.md
Package documentation links./references/external-resources.md
Tutorial recommendations with provenance./references/external-resources.md
Assignment operator (<- vs =)./references/gotchas.md
TRUE/FALSE vs True/False./references/gotchas.md
1-indexed vector access./references/gotchas.md
Factor vs Categorical pitfalls./references/gotchas.md
library() vs import habits./references/gotchas.md
NA propagation surprises./references/gotchas.md
Vectorized operations expectations./references/gotchas.md
Copying semantics (R copy-on-modify vs Python references)./references/gotchas.md
Logical operators (& /vs and / or)
String interpolation (glue vs f-strings)./references/gotchas.md
apply family vs map/list comprehension./references/gotchas.md
Coordinate systems (coord_flip, coord_polar)./references/visualization.md
Stat layers (stat_smooth, stat_summary)./references/visualization.md
Color palette mapping (viridis, brewer)./references/visualization.md
Multi-panel layouts (patchwork vs subplot)./references/visualization.md
Parallel trends testing./references/causal-inference.md
Environment/workspace differences (.RData vs nothing)./references/workflow-environment.md
Debugging workflow (browser() vs breakpoint())./references/workflow-environment.md
R help system (?func) vs Python help(func)./references/workflow-environment.md
Cheat sheet and quick-reference links./references/external-resources.md
Community resources (Stack Overflow tags, forums)./references/external-resources.md

Signals

GitHub stars
235
Forks
34
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
python-r-translation
Source
github.com/daaf-contribution-community/daaf