Programming Basics

Tip

This page covers programming basics with examples in R and Python. Every code block is interactive: edit the code and press Run Code to see what changes. We encourage you to play around!

You can click to switch between languaged. Picking R or Python in one tabset switches every tabset on the page. Callouts marked R vs Python point out the places where the two languages behave differently in notable ways.

Basics

The most common way you will interact with R and Python is through a REPL (read-evaluate-print-loop):

  • You type out one or more statements (instructions)
  • You ask the language interpreter to execute (evaluate) them
  • It returns (prints) any output
  • Repeat

Run the code cell below to see the output of 1+1

Values, variables, and types

To do more than simple calculations we need to store inputs and outputs (values). To do this we declare variables, which can hold different types of values.

Text

To store text we wrap it in single '' or double "" quotes to create a string:

WarningR vs Python: assignment

R assigns with <- (it also accepts =). Python only uses =. In both languages a single = assigns a value and a double == compares two values.

Numbers

We typically work with two kinds of numbers: integers (whole numbers) and floats (numbers with decimals):

WarningR vs Python: integers and floats

R treats both 3 and 3.1 as numeric unless you ask for an integer with 3L. Python keeps int and float separate, but mixing them is safe as Python will convert to higher precision floats for you.

Booleans

Booleans store whether something is true or false:

WarningR vs Python: spelling booleans

R writes TRUE and FALSE. Python writes True and False. Typing TRUE in Python gives a NameError because Python thinks you are referring to a variable you never defined.

Comparisons

Comparing values produces booleans. We combine comparisons with and, or, and not:

What happens when we compare a number to a string?

ImportantR vs Python: converting between types

R quietly converts types for you when it can. Python never does, and raises a TypeError instead. To mix types in Python, convert them yourself with str(), int(), or float():

Python’s strictness is a feature. Silent conversion is a common source of bugs in data analysis.

Containers

Most data analysis involves many values at once. Both languages have a container for an ordered sequence of values:

NoteVectors vs lists

An R vector holds values of a single type (all numbers, or all strings). A Python list can mix types, so [1, "two", 3.0] is allowed. In practice you will rarely want a mixed list.

Indexing and slicing

To pull out individual items we index with square brackets. To pull out a range of items we slice:

ImportantR vs Python: counting from 0 or 1

This is the first big difference to get used to. R counts from 1, Python counts from 0, and Python slices exclude the stop position. The rule applies everywhere: the first row of a Python dataframe is row 0.

What you want R Python
First item x[1] x[0]
First 3 items x[1:3] x[0:3] or x[:3]
Last item x[length(x)] or tail(x, 1) x[-1]

Negative numbers also mean different things. In R x[-1] removes the first item. In Python x[-1] returns the last item.

Adding items

WarningR vs Python: .append() returns nothing

In R you get a new vector back and assign it. In Python .append() modifies the existing list and returns None. Never write fruits = fruits.append("fig"), which overwrites your list with None. Call fruits.append("fig") on its own line instead.

Named collections

Sometimes we want to look values up by name instead of position. Think of these as one row of a dataframe: each name is a column and each value is that row’s entry:

Control flow

So far every line has run once, top to bottom. Control flow lets us make decisions and repeat work.

Conditionals

WarningR vs Python: braces vs indentation

R uses { } to mark which lines belong to an if or for. Python uses a : followed by indentation, and the indentation is not optional. Forgetting to indent gives an IndentationError:

Most editors indent for you, so you will usually hit this error when editing existing code.

Loops

A for loop runs the same block of code once for each item in a collection:

WarningR vs Python: 1:3 vs range(3)

R’s 1:3 gives 1, 2, 3. Python’s range(3) gives 0, 1, 2. Like slicing, it starts at 0 and stops before 3. To get 1, 2, 3 in Python write range(1, 4).

Functions and methods

A function packages up a block of code so you can reuse it. You have been calling built-in functions all along (print(), length(), len()). Here is how to write your own:

WarningR vs Python: defining functions

R uses the function keyword and braces. Python uses def, a colon, and indentation. R returns the last expression automatically, so return() is optional. Python only returns what you explicitly return.

Methods

Python attaches some functions directly to values. These are methods, and you call them with a .:

NoteR vs Python: methods and chaining

When you see my_string.upper() in Python, read it as toupper(my_string). Methods let Python chain steps as object.method().method(), which plays the same role as R’s pipe |> (you will also see the older %>% from the tidyverse). But not every Python method is chainable: .append() above changed the list and returned nothing.

Libraries

Neither language ships with everything you need for data analysis. Libraries (also called packages) add functions for reading data, plotting, and statistics. You load them at the top of your code:

WarningR vs Python: using a library’s functions

After library(dplyr) in R, you call filter() directly. After import polars as pl in Python, you call pl.read_csv() with the nickname in front. Python is explicit about where every function comes from, which avoids two libraries clashing over the same name. The nicknames are conventions everyone uses.

Tabular data

Most data analysis happens in a dataframe, a table with named columns and one row per observation. The examples use the Palmer Penguins dataset, already loaded in your browser as penguins.csv:

Notedplyr and polars speak the same language

filter, group_by, and summarize/agg do the same jobs in both. R pipes with |>; Python chains with . and wraps the whole chain in parentheses so it can span lines.

Statistics

Debugging

An error is the language telling you what went wrong and where. Read an error message from the bottom up: the last line names the problem, and the lines above show where it happened. Here are the four you will meet most often:

Unknown name

Almost always a typo, or a variable you have not defined yet (did you run the earlier cell?).

Syntax error

The language cannot parse what you typed: an unclosed parenthesis or quote, a stray line break, or a missing : in Python.

Wrong type

The operation is fine but the input is the wrong kind of value. Check what you have with class() or type().

Position that does not exist

WarningR vs Python: R is quieter

R returns NA for a position that does not exist and keeps going. Python stops with an IndexError. Python’s habit of stopping early is annoying in the moment but catches mistakes that R would let slip through to your results.

A 60-second debugging workflow

  1. Read the last line of the error and name the type of problem out loud.
  2. Check your assumptions at that line: class(x) or type(x), length(x) or len(x), the column names of your dataframe.
  3. Shrink the problem: run just the failing piece on its own. For a broken chain, remove steps from the end until it works, then add them back one at a time.
  4. Change one thing and rerun. Rerunning is free.
  5. Still stuck? Paste the full error message into a search engine or AI assistant. The exact wording is what makes errors searchable. See Working with AI for how to do this well.

Getting help

Both languages have built-in documentation for every function:

Playground

Feel free to use the empty code blocks below try to things out

Back to top