Course Introduction

Welcome to STA 295: Introduction to Statistical Learning. The course website is available at https://rebelskyw.cs.grinnell.edu/sta-295-spring-2025 and the syllabus is available at https://rebelskyw.cs.grinnell.edu/sta-295-spring-2025-syllabus/.

Outline of Today

  1. Discuss the Syllabus and Course Expectations
  2. Discuss Class Format
  3. Introduction to Statistical Learning
  4. Review of R
  5. Course Schedule for the first couple weeks

Syllabus

  1. Attendance:
    1. Attendance is important. Please let me know all days that you will miss ASAP so that I can better assign lab partners.
  2. Due dates:
    1. Readings are due 10pm the day before class. Submit a paragraph or so to Gradescope
    2. Homework assignments are due at 10pm on Friday. Late submissions can be turned in until 10pm Sunday.
    3. Labs are due at 10pm on Friday. Late submissions can be turned in until 10pm Sunday.
    4. Projects are generally dye at 10pm on Friday, exceptions include Final project group (5pm week 7) and the Final project (5pm week 14)
  3. Tokens
  4. Grade Matrix

Class Format

This is a pseudo-workshop style class. I believe that learning occurs by doing and working together improves retention. The general class format as is as follows (all times approximate):

  1. Class Announcements (5-10min)
  2. Lecture (10-20min)
  3. Work on Lab with your randomly assigned partner
  4. Class wrap up (5-10min): reminder of the goals of todays lab

Notes:

  1. If you don’t finish the lab in class, you will need to finish them outside of class. You can either continue to work with your partner, or you can finish the lab on your own.
  2. If you finish the lab early:
    1. Quietly work on your homework for the week
    2. Work on homework for another course

Lab format

The “Lab” section is something you will work on with a partner using paired programming, a framework defined as follows:

  • One partner is the driver, who physically writes code and operates the computer
  • One partner is the navigator, who reviews the actions of the driver and provides feedback and guidance

Partners are encouraged to switch roles throughout the “Lab” section, but for the first few labs the less experienced coder should spend more time as the driver.

Directions for all labs (read before starting)

  1. Please work together with your assigned partner. Make sure you both fully understand something before moving on.
  2. Record your answers to lab questions separately from the lab’s examples. You and your partner should only turn in responses to lab questions, nothing more and nothing less.
  3. Ask for help, clarification, or even just a check-in if anything seems unclear.

\(~\)

Introduction to Statistical Learning

What is Statistical Learning?

  • A set of tools for understanding data
  • Supervised vs Unsupervised
    • Supervised: Predict Output from Input
    • Unsupervised: Find relationships between inputs
  • Regression vs Classification:
    • Regression: Predicting (estimating) Numeric value of quantitative output variable
    • Classification: Predicting (classifying) Qualitative level of categorical output variable

Format of this course:

  • Mostly supervised models (discuss with your neighbor: Why?)
  • Course Premises based on ISL:
    • Concentrate on presenting most widely applicable methods
    • You should understand how the methods work
    • You don’t need to be able to construct the underlying method
    • You want to apply statistical learning to real world problems

Lab: R basics

Lab: Class work

The Layout of R Studio

After you open RStudio, the first thing you’ll want to do is open a file to work in. You can do this by navigating: File -> New File -> RScript, which will open a new window in the top left of the RStudio interface for you to work in. At this point you should see four panels:

  1. Your R Script (top left)
  2. The Console (bottom left)
  3. Your Environment (top right)
  4. The Files/Plots/Help viewer (bottom right)

An R Script is like a text-file that stores your code while you work on it. At any point you can send some or all of the code in your R Script to the Console to execute. You can also type commands directly into the Console. The Console will echo any code you run, and it will display any textual/numeric output generated by your code.

The Environment shows you the names of data sets, variables, and user-created functions that have been loaded into your work space and can be accessed by your code. The Files/Plots/Help Viewer will display graphics generated by your code and a few other useful entities (like help documentation and file trees).

\(~\)

Packages

To facilitate more complex tasks in R, many people have developed their own sets of functions known as packages. If you plan on working with a new package for the first time, it must be installed:

install.packages("ggplot2")

Once a package is installed, it still needs to be loaded into your R session using the library() function (or require()) before its contents can be used.

You’ll need to re-load a package every time you open R Studio, but you’ll only need to install it once.

my_data <- read.csv("https://remiller1450.github.io/data/HappyPlanet.csv")
library(ggplot2)
library(dplyr)
qplot(my_data$Region) # qplot is a function in the package ggplot2

\(~\)

R scripts vs R markdown

R Scripts are built to contain only executable R code and comments.

R Studio supports several other types of files, some of which use the “Markdown” authoring framework. An “R Markdown” file allows you to both:

  1. Write and execute R code
  2. Generate a high quality, reproducible report

To use R Markdown, you’ll need the rmarkdown package. In order to knit to pdf instead of html, you will likely need the tinytex package:

install.packages("rmarkdown")
library("rmarkdown")
install.packages("tinytex")
tinytex::install_tinytex()

Once you have the package installed and loaded, you can create a new R Markdown file by selecting: File -> New File -> R Markdown.

At the top of the document is the header:

  • This section initiated by three ‘-’ characters and closed by another three ‘-’ characters
  • It contains the title, author, etc. that appears at the top of the document created by your code
  • You can use it to add elements like a table of contents, page numbers, etc.

The second thing you’ll see is a code chunk:

  • Code chunks are initiated by \(\text{```\{r\}}\) and closed by \(\text{```}\)
  • The \(\text{```}\) wrappers tell R Markdown that what appears inside is code that should be executed. The first code chunk, initiated by \(\text{```\{r setup\}}\) sets up options that will be used in executing your R code when your report is built. For now, you should keep this chunk as it appears and place your actual code inside of other code chunks.
  • You can execute the R code in a chunk by clicking the small green arrow in the upper right corner. You can also highlight individual code pieces and execute them using Ctrl-Enter.

Next you’ll see section headers:

  • Sections are created using strings of the \(\#\) character.
  • The number of \(\#\) characters used determines the level (size) of the header.

Finally, R Markdown allows you to type ordinary text outside of code chunks. Thus, you can easily integrate written text into the same document as your code and its output.

The primary purpose of R Markdown is to create documents that blend R code, output, and text into a polished report. To generate this document you must compile your R Markdown file using the “Knit” button (a blue yarn ball icon) located towards the upper left part of your screen.

The R Markdown cheat sheet can be found here: https://raw.githubusercontent.com/rstudio/cheatsheets/main/rmarkdown.pdf

\(~\)

Question #1: Create a new R Markdown file and delete all of the template code that appears beneath the “r setup” code block. Change the title to “Lab #1” and the author to your name(s). Next, create section labels for each question in the lab using three \(\#\) characters followed by “Question X” (where X is the number of the question).

Question #1 (continued): R Markdown will use LaTex typesetting for any text wrapped in \(\$\) characters. For example, \(\$\text{\\beta}\$\) will appear as a the Greek letter \(\beta\) after you knit your document. To practice this, add a label for Question #1 and below it include \(\$\text{H_0: \\mu = 0}\$\) in a sentence (the sentence can say anything, but it should not be inside an R code chunk or a section header).

\(~\)

Using R

R is an interpreted programming language, which allows you to have the computer execute any piece of code contained your R Script at any time without a lengthy compiling process.

To run a single piece of code, simply highlight it and either hit Ctrl-Enter or click on the “Run” button near the top right corner of your R Script. You should see an echo of the code you ran in the Console, along with any response generated by that code.

4 + 6 - (24/6)
## [1] 6
5 ^ 2 + 2 * 2
## [1] 29

The examples shown above demonstrate how R can be used as a calculator. However, most of code we will write will rely upon functions, or pre-built units of code that translate one or more inputs into one or more outputs.

log(x = 4, base = 2)
## [1] 2

The example above demonstrates the log() function. The input named “x” is set to be 4, and the input named “base” is set to 2. The labels given to these inputs, “x” and “base”, are the function’s arguments. The function returns the output “2”, which is \(\text{log}_2(4)\). Note that log(4, 2) will also produce the output “2” as any unlabeled inputs are mapped to arguments in the order defined by the creator of the function.

\(~\)

Help Documentation

You’ll eventually end up memorizing the arguments of common R functions; however, while you’re learning I strongly encourage you to read the help documentation for any R function used in your code. You can access a function’s documentation by typing a ? in front of the function name and submitting to the console.

?log

In addition, if you think there should be a function but you don’t know what it is called, you can use two ‘??’:

??logarithm

\(~\)

Adding Comments

When coding, it is good practice to include comments that describe what your code is doing. In R the character “#” is used to start a comment. Everything appearing on the same line to the right of the “#” will not be executed when that line is submitted to the console.

# This entire line is a comment and will do nothing if run
1:6 # The command "1:6" appears before this comment
## [1] 1 2 3 4 5 6

In your R Script, comments appear in green. You also should remember that the “#” starts a comment only for a single line of your R Script, so long comments requiring multiple lines should each begin with their own “#”.

\(~\)

Lab: Partner work

Loading Data

An important part of data science is reproducibility, or the ability for two people to independently replicate the results of a project.

To ensure reproducibility, every data analysis should begin by importing raw data into R and manipulating it used documented (commented) code. Further, the raw data should be imported using functions, such as read.csv, instead of the point and click interface provided by the “Import Dataset” button (at the top of the environment pane).

Below are two different examples:

## Loading a CSV file from a web URL (storing it as "my_data")
my_data <- read.csv("https://some_webpage/some_data.csv")
## Loading a CSV file with a local file path
my_data <- read.csv("H:/path_to_my_data/my_data.csv")

A few things to note.

  1. Both <- or = can be used to assign something to a named object. The <- operator will create the object globally, while = will create the object locally in the environment where it was used. For the purposes of this course, we can use the two interchangeably since our code will “live” in the global environment.
  2. File paths must use / or \\. A single \ is used by R to start an instance of a special text character. For example, \n creates a new line in a string of text.

\(~\)

Loading a single file

Question 2 part a Add code to your script that uses the read.csv() function to create an object named my_data that contains the “Happy Planet” data stored at: https://remiller1450.github.io/data/HappyPlanet.csv

After running your Question #2 code, an entry named “my_data” should appear in the Environment panel (top right).

You can click on the small arrow icon to reveal the data’s structure, or you can click on the object’s name to view the data in spreadsheet format.

Question 2 part b Inspect the structure of my_data and view the data set in spreadsheet format. In an R comment, briefly describe how this data set is structured (ie: what does each row and column represent, what are some of the columns, etc.)

\(~\)

Loading multiple files

Question 3 part a Download the data from this folder of data files to your Lab Data folder. Run the following line (rewrite it to match your username) to verify the .xlsx files are there

list.files(path = "C:/Users/wrebe/Documents/2025FallSTA230/Labs/Data")
## [1] "run18_treatment.xlsx" "run21_control.xlsx"   "run34_control.xlsx"  
## [4] "run35_treatment.xlsx"

Now let’s suppose we want to find the means of the variable “VDS.Veh.Speed” for each participant file. Note that these are excel files (not .csv files), so we must first load (and possibly install) the readxl package in order to read them into R.

We then can iterate through these files using a for loop, storing the mean of each participant:

library(readxl)
my_dir = "C:/Users/wrebe/Documents/2025FallSTA230/Labs/Data"
my_files <- list.files(path = my_dir)  ## List of file names in your directory

means <- numeric(length(my_files))                           ## Set up storage object
for(i in 1:length(my_files)){                                ## Loop over each file
  temp <- read_excel(paste0(my_dir, "/", my_files[i]))       ## Read by appending file name to the path prefix using paste0()
  means[i] <- mean(temp$VDS.Veh.Speed)                       ## Store the mean of the current file
}
print(means)
## [1] 24.91347 35.62761 56.93149 26.81412

Question 3 part b Using the example above as a template, find the standard deviations (using the sd() function) of each participant file. Store these standard deviations in an object named “sds” and print them as part of your answer.

\(~\)

Row binding

Sometimes it can be useful to aggregate several data frames with the same structure into one larger data frame. For example, we might want to combine all four participant files from Question #11 into a combined data frame. Or, perhaps we want to aggregate several years of data from the same source. These tasks can be handled by the rbind() function, which will append the rows of one or more data frames to an initial data frame (provided the column names match):

df1 <- data.frame(Year = 2019, val = rnorm(3))
df2 <- data.frame(Year = 2020, val = rnorm(3, mean = 10))

rbind(df1, df2)
##   Year        val
## 1 2019 -0.1702080
## 2 2019 -0.6842358
## 3 2019  0.4481293
## 4 2020  9.4247378
## 5 2020  8.2301953
## 6 2020  9.5125080

Note that this result could also be achieved using full_join() (though I personally find that approach less intuitive):

full_join(x = df1, y = df2)
## Joining with `by = join_by(Year, val)`
##   Year        val
## 1 2019 -0.1702080
## 2 2019 -0.6842358
## 3 2019  0.4481293
## 4 2020  9.4247378
## 5 2020  8.2301953
## 6 2020  9.5125080

However, rbind() has the advantage of easily being able to bind an arbitrary number of data frames in a single command:

df3 <- data.frame(Year = 2021, val = rnorm(3, mean = -5)) ## How about a third year?
rbind(df1, df2, df3)
##   Year        val
## 1 2019 -0.1702080
## 2 2019 -0.6842358
## 3 2019  0.4481293
## 4 2020  9.4247378
## 5 2020  8.2301953
## 6 2020  9.5125080
## 7 2021 -5.9427835
## 8 2021 -5.6620627
## 9 2021 -4.4519756

Question #4: Use rbind() to combine the four data files in the “experiment” folder (used in Question #4) into a single data frame. Be sure to add a participant identifier to each file as a preliminary step. Print the dimensions of the resulting data frame using dim(). Hint: You may choose to use rbind() inside a for loop to repeatedly append new rows onto an existing data frame. In this approach, your initial data frame can be NULL if you don’t want to anticipate the structure of the files.

Logical Conditions and Subsetting

Often we want to access all data that meet certain criteria. For example, we may want to analyze all countries with a life expectancy above 80. To accomplish this, we’ll need to use logical operators:

## This returns a logical vector using the condition "> 80"
my_data$LifeExpectancy > 80

A few logical operators you should know of are:

Operator | Description

== | equal to != | not equal to > | great than >= | greater than or equal to <| less than <=| less than or equal to &| and || or
! | negation (“not”)

The which() function can be used to identify the indices of elements of within an object containing the logical value TRUE, for example:

## This returns the positions where the condition evaluated to TRUE
which(my_data$LifeExpectancy > 80 )

This result could then be used as indices to subset my_data:

## sub-setting via indices
keep_idx <- which(my_data$LifeExpectancy > 80)
my_subset <- my_data[keep_idx, ]

The approach shown above is a bit cumbersome. As an alternative we can use the subset() function alongside logical expressions:

## Example #1
Ex1 <- subset(my_data, LifeExpectancy > 80)

In example #1, the data frame Ex1 will contain the subset of countries with life expectancy above 80. Notice how the subset() function knows that LifeExpectancy is a component of my_data.

## Example #2
Ex2 <- subset(my_data, LifeExpectancy <= 70 & Happiness > 6)

In example #2, the & operator is used to create a data frame, Ex2, containing all countries with a life expectancy of 70 or below and a happiness score above 6.

## Example #3
Ex3 <- subset(my_data, LifeExpectancy <= 70 | Happiness > 6)

In example #3, the | operator is used create a data frame of all countries with a life expectancy of 70 or below or a happiness score above 6. Notice the different dimensions of Ex2 and Ex3:

dim(Ex2)
## [1]  9 11
dim(Ex3)
## [1] 118  11

Question #5: Create a data frame named “Q6” that contains all countries with a population over 100 million that also have a happiness score of 6 or lower. Then, print the number of rows of this data frame.

\(~\)

Wrap-up

Lab goals:

Hopefully this lab was mostly review. In this lab we reviewed the following:

  • Rstudio Basics
    • Layout
    • Functions
    • Help
  • Loading Data
    • Single File
    • Multiple Files
  • Subsetting Data

Course Schedule for the first few weeks:

  1. Today: Introduction to the course
  2. Thursday: Further Introduction to the course
  3. Tuesday 28: TBD, I will likely not be here
  4. Thursday 30: Foundations of Statistical Learning
  5. Tuesday 04: Linear Regression
  6. Thursday 06: Multiple Linear Regression

Reminders for next class:

  • Homework 0 is due Friday at 10pm
  • This Lab is due Friday at 10pm
  • The reading assignment for Chapter 1 of the text is due Tomorrow at 10pm