Intro and Plotting

Alejandro Schuler

Learning Goals:

  • issue commands to R using the Rstudio REPL interface
  • load a package into R
  • read some tabluar data into R
  • visualize tabluar data using ggplot geoms, aesthetics, and facets

Basics

Console

The R console window is the left (or lower-left) window in RStudio. The R console uses a “read, eval, print” loop. This is sometimes called a REPL.

  • Read: R reads what you type …
  • Eval: R evaluates it …
  • Print: R prints the result …
  • Loop: (repeat forever)

  • The box contains an expression that will be evaluated by R, followed by the result of evaluating that expression.
1 + 2
[1] 3
  • 3 is the answer

  • Ignore the [1] for now.

  • R performs operations (called functions) on data and values

  • These can be composed arbitrarily

log(1+3)
[1] 1.386294
paste("The answer is", log(1+3))
[1] "The answer is 1.38629436111989"

How do I…

  • typing ?function_name gives you information about what the function does
  • Google is your friend. Try “function_name R language” or “how do I X in R?”. I also strongly recommend using “tidyverse” in your queries or the name of a tidyverse package (more in a moment) that has related functions
  • stackoverflow is your friend. It might take some scrolling, but you will eventually find what you need
  • LLMs…

Why learn this when LLMs can do it?

  • Anthropic’s Claude code (using eg Opus 5) or OpenAI’s codex (using eg Sol) can do everything you will learn about in this class and probably also in any quant class you’ll take in your MPH.

Why learn this when LLMs can do it?

Discuss in your groups.

Quadratic Equation

Solutions to a polynomial equation \(ax^2 + bx + c = 0\) are given by \[x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}\]

Figure out how to use R functions and operations for square roots, exponentiation, and multiplication to calculate x given a=3, b=14, c=-5 (no LLMs).

  • How did this feel? What was your emotional reaction when you saw the question?
  • What did you learn? What did you notice?

Packages

  • The amazing thing about programming is that you are not limited to what is built into the language
  • Millions of R users have written their own functions that you can use
  • These are bundled together into packages
  • To use functions that aren’t built into the “base” language, you have to tell R to first go download the relevant code, and then to load it in the current session
install.packages("QuadRoot")
library(QuadRoot)
QuadRoot(c(3,14,-5))
[1] "The two x-intercepts for the quadratic equation are 0.3333 and -5.0000."

  • The tidyverse package has a function called read_csv() that lets you read csv (comma-separated values) files into R.
  • csv is a common format for data to come in, and it’s easy to export csv files from microsoft excel, for instance.
# I have a file called "nhanes_subset.csv" on github that we can read from the URL
nhanes = read_csv("https://raw.githubusercontent.com/alejandroschuler/r4ds-courses/mph-nhanes/data/nhanes/nhanes_subset.csv")
Error in read_csv("https://raw.githubusercontent.com/alejandroschuler/r4ds-courses/mph-nhanes/data/nhanes/nhanes_subset.csv"): could not find function "read_csv"
  • This fails because I haven’t yet installed and loaded the tidyverse package
install.packages("tidyverse") # go download the package called "tidyverse"- only have to do this once
library("tidyverse") # load the package into the current R session - do this every time you use R and need functions from this package
nhanes = read_csv("https://raw.githubusercontent.com/alejandroschuler/r4ds-courses/mph-nhanes/data/nhanes/nhanes_subset.csv")
  • Now there is no error message

  • packages only need to be loaded once per R session (session starts when you open R studio, ends when you shut it down)
  • once the package is loaded it doesn’t need to be loaded again before each function call
poly = read_csv("https://raw.githubusercontent.com/alejandroschuler/r4ds-courses/mph-nhanes/data/poly.csv") # reading another csv file

Visualizing Data

Data analysis workflow

  1. Read data into R (done!)
  2. Manipulate data
  3. Get results, make plots and figures

Getting your data in R

  • Getting your data into R is easy. We already saw, for example:
nhanes = read_csv("https://raw.githubusercontent.com/alejandroschuler/r4ds-courses/mph-nhanes/data/nhanes/nhanes_subset.csv")
  • read_csv() requires you to tell it where to find the file you want to read in
    • Windows, e.g.: "C:\Users\me\Desktop\myfile.csv"
    • Mac, e.g.: "/Users/me/Desktop/myfile.csv"
    • Internet, e.g.: "http://www.mywebsite.com/myfile.csv"
  • If your data is not already in csv format, google “covert X format to csv” or “read X format data in R”
  • We’ll learn the details of this later, but this is enough to get you started!

Looking at data

  • nhanes is now a dataset loaded into R. To look at it, just type
nhanes
# A tibble: 59 x 11
   id             age sex   race  diabetes glucose hba1c   bmi waist_cm bp_sys_1
   <chr>        <dbl> <chr> <chr> <chr>      <dbl> <dbl> <dbl>    <dbl>    <dbl>
 1 NHANES-1001~    72 male  Mexi~ Yes          124   6.8  31.5    107.       124
 2 NHANES-1001~    80 fema~ White Yes           95   6.7  26       87        180
 3 NHANES-1002~    66 male  White Yes          171   7.9  26.1    105.       120
 4 NHANES-1002~    65 fema~ Black Yes          157   7.4  34.4    102.       102
 5 NHANES-1004~    31 male  White No            98   4.8  23.2     85.3      112
 6 NHANES-1008~    80 male  Mexi~ Yes          174   7.7  32.1    120.       156
 7 NHANES-1011~    49 fema~ Black No           107   5.7  39.3    112.       128
 8 NHANES-1012~    65 fema~ Black Yes          150   8.1  30.8    114.       128
 9 NHANES-1013~    80 fema~ White Yes          165   8.7  30      118.       156
10 NHANES-1014~    53 male  Asian No           104   5.6  28.6     99.1      126
# i 49 more rows
# i 1 more variable: cholesterol <dbl>

This is a data frame, one of the most powerful features in R (a “tibble” is a kind of data frame). - Similar to an Excel spreadsheet. - One row ~ one instance of some (real-world) object. - One column ~ one variable, containing the values for the corresponding instances. - All the values in one column should be of the same type (a number, a category, text, etc.), but different columns can be of different types.

The Dataset

nhanes
# A tibble: 59 x 11
   id             age sex   race  diabetes glucose hba1c   bmi waist_cm bp_sys_1
   <chr>        <dbl> <chr> <chr> <chr>      <dbl> <dbl> <dbl>    <dbl>    <dbl>
 1 NHANES-1001~    72 male  Mexi~ Yes          124   6.8  31.5    107.       124
 2 NHANES-1001~    80 fema~ White Yes           95   6.7  26       87        180
 3 NHANES-1002~    66 male  White Yes          171   7.9  26.1    105.       120
 4 NHANES-1002~    65 fema~ Black Yes          157   7.4  34.4    102.       102
 5 NHANES-1004~    31 male  White No            98   4.8  23.2     85.3      112
 6 NHANES-1008~    80 male  Mexi~ Yes          174   7.7  32.1    120.       156
 7 NHANES-1011~    49 fema~ Black No           107   5.7  39.3    112.       128
 8 NHANES-1012~    65 fema~ Black Yes          150   8.1  30.8    114.       128
 9 NHANES-1013~    80 fema~ White Yes          165   8.7  30      118.       156
10 NHANES-1014~    53 male  Asian No           104   5.6  28.6     99.1      126
# i 49 more rows
# i 1 more variable: cholesterol <dbl>

This is a subset of NHANES, the CDC’s National Health and Nutrition Examination Survey. NHANES sends a mobile clinic around the country, interviews a nationally representative sample of Americans, and gives each of them a physical exam and a blood draw.

  • 30 participants with diagnosed diabetes, 29 without
  • We have basic demographics as well as several body measurements and lab values.
  • Let’s see if we can find anything interesting from this already-generated data!

Investigating a relationship

Let’s say we’re curious about the relationship between two lab values, glucose and hba1c.

  • Can we use R to make a plot of these two variables?
ggplot(nhanes) + 
  geom_point(aes(x = glucose, y = hba1c))

  • ggplot(dataset) says “start a chart with this dataset”
  • + geom_point(...) says “put points on this chart”
  • aes(x=x_values y=y_values) says “map the values in the column x_values to the x-axis, and map the values in the column y_values to the y-axis” (aes is short for aesthetic)

ggplot

ggplot(nhanes) + 
  geom_point(aes(x = waist_cm, y = bmi))

  • ggplot is short for “grammar of graphics plot”
    • This is a language for describing how data get linked to visual elements
  • ggplot() and geom_point() are functions imported from the ggplot2 package, which is one of the “sub-packages” of the tidyverse package we loaded earlier

Exercise: comparing lab values

Make a scatterplot of diabetes vs hba1c (another lab value in the dataset). The result should look like this:

Investigating a relationship

Let’s say we’re curious about the relationship between glucose and hba1c.

  • What’s going on here? It seems like there are two clusters.
  • What is driving this clustering? Age? Sex? Race? Diabetes?

Aesthetics

  • Aesthetics aren’t just for mapping columns to the x- and y-axis
  • You can also use them to assign color, for instance
ggplot(nhanes) + 
  geom_point(aes(x = glucose, 
                 y = hba1c,
                 color = diabetes))
  • Aesthetics aren’t just for mapping columns to the x- and y-axis
  • We could have used a shape
ggplot(nhanes) + 
  geom_point(aes(
    x = glucose, 
    y = hba1c, 
    shape=diabetes
  )) 
  • Or size
ggplot(nhanes) + 
  geom_point(aes(
    x = glucose, 
    y = hba1c, 
    size=race
  )) 
  • This one doesn’t really make sense because we’re mapping a categorical variable to an aesthetic that can take continuous values that imply some ordering
  • If we set a property outside of the aesthetic, it no longer maps that property to a column.
ggplot(nhanes) + 
  geom_point(
    aes(
      x = glucose, 
      y = hba1c
    ),
    color = "blue"
  ) 
  • However, we can use this to assign fixed properties to the plot that don’t depend on the data

Exercise: Plot

Can you recreate this plot?

Exercise [together]

What will this do? Why?

ggplot(nhanes) + 
  geom_point(aes(x = glucose, y = hba1c, color = "blue"))

Geoms

ggplot(nhanes) + 
  geom_point(aes(x = glucose, y = hba1c))

ggplot(nhanes) + 
  geom_smooth(aes(x = glucose, y = hba1c))

  • Both these plots represent the same data, but they use a different geometric representation (“geom”)
  • e.g. bar chart vs. line chart, etc.
  • R graph gallery is a great resource to help you design your plot and pick the right geom: r-graph-gallery.com
  • Different geoms are configured to work with different aesthetics.
  • e.g. you can set the shape of a point, but you can’t set the “shape” of a line.
  • On the other hand, you can set the “line type” of a line:
ggplot(nhanes) + 
  geom_smooth(aes(x = glucose, y = hba1c, linetype = diabetes))
  • Use e.g. ?geom_point to see what aesthetics are expected or allowed
  • It’s possible to add multiple geoms to the same plot
ggplot(nhanes) + 
  geom_smooth(aes(x = glucose, y = hba1c, color = diabetes)) + 
  geom_point(aes(x = glucose, y = hba1c, color = diabetes))
  • To assign the same aesthetics to all geoms, pass the aesthetics to the ggplot function directly instead of to each geom individually
ggplot(nhanes, aes(x = glucose, y = hba1c, color = diabetes)) + 
  geom_smooth() + 
  geom_point()
  • You can also use different mappings in different geoms
ggplot(nhanes, mapping = aes(x = glucose, y = hba1c)) + 
  geom_point(aes(color = race)) + 
  geom_smooth()

Exercise

Use google or other resources to figure out how to receate this plot in R:

ggplot(nhanes) + 
  ...
  • What might the name of this geom be? What properties of the plot (aesthetics) are mapped to what columns of the data?
  • If you accomplish making the plot, can you figure out how to change the colors of the groups?

Facets

  • Aesthetics are useful for mapping columns to particular properties of a single plot
  • Use facets to generate multiple plots with shared structure
ggplot(nhanes) + 
  geom_point(aes(x = glucose, y = hba1c)) + 
  facet_wrap(vars(diabetes), nrow = 2)
  • facet_wrap is good for faceting according to unordered categories
  • facet_grid is better for ordered categories, and can be used with two variables
ggplot(nhanes) + 
  geom_point(aes(x = glucose, y = hba1c)) + 
  facet_grid(rows=vars(diabetes), cols=vars(sex))

Exercise

Use ggplot to investigate the relationship between these measurements and diabetes using any combination of any kinds of plots that you like. Which measurements are most associated with diabetes? Does this vary by race, age, or assigned sex at birth?

For some plots it may be helpful to reformat your data using this code (we’ll learn how to do this on day 4):

measure_names = names(nhanes)[6:11]
reformatted_nhanes = pivot_longer(nhanes, all_of(measure_names), names_to='measure', values_to='value')
reformatted_nhanes
# A tibble: 354 x 7
   id              age sex    race             diabetes measure     value
   <chr>         <dbl> <chr>  <chr>            <chr>    <chr>       <dbl>
 1 NHANES-100129    72 male   Mexican American Yes      glucose     124  
 2 NHANES-100129    72 male   Mexican American Yes      hba1c         6.8
 3 NHANES-100129    72 male   Mexican American Yes      bmi          31.5
 4 NHANES-100129    72 male   Mexican American Yes      waist_cm    107. 
 5 NHANES-100129    72 male   Mexican American Yes      bp_sys_1    124  
 6 NHANES-100129    72 male   Mexican American Yes      cholesterol 170  
 7 NHANES-100188    80 female White            Yes      glucose      95  
 8 NHANES-100188    80 female White            Yes      hba1c         6.7
 9 NHANES-100188    80 female White            Yes      bmi          26  
10 NHANES-100188    80 female White            Yes      waist_cm     87  
# i 344 more rows