๐Ÿ—“๏ธ Week 01
Introduction to R

STAT 204 โ€“ Introduction to Statistical Data Analysis

01 Sep 2025

Welcome!

Your instructor

Photo of Instructor
Prof. Marcela Alfaro Cordoba
Associate Professor of Teaching - Statistics
R Enthusiast & Stats and Data Science Educator
  • ๐Ÿƒ 15 years teaching R (intro & advanced)
  • Background: Statistical & Data Science Education + Applied Stats
  • Originally from Costa Rica ๐ŸŒŠ
  • Workshops in academia & learning communities

R programming
stats
data visualization
data science
open and reproducible science

Course logistics

๐Ÿ“ง Communication

  • Primary: Ed Discussion (fastest response)
  • Email: macordob@ucsc.edu
  • Office Hours: Tuesdays and Thursdays after lecture

๐Ÿ“š Resources

  • Course Website: Course URL
  • Canvas: Assignments and grades
  • Textbook: several, all available via library

Syllabus

You can also find it on Canvas

Questions?

Learning objectives

By the end of week 1, you will be able to:

  • Navigate RStudio interface confidently and understand Rโ€™s history and advantages ๐Ÿ–ฅ๏ธ๐Ÿ“š
  • Use R as a calculator and understand assignment operators (<- vs =) ๐Ÿงฎ
  • Create and work with different data types (numeric, character, logical, factor, complex) ๐Ÿ“Š
  • Master Rโ€™s case sensitivity and manage your workspace environment ๐Ÿ”ค
  • Use basic R functions, get help effectively, and install packages ๐Ÿ†˜๐Ÿ“ฆ
  • Create and manipulate vectors using multiple methods (c(), seq(), rep()) ๐Ÿ“ˆ
  • Handle special values (NA, NaN, Inf) and perform vector operations ๐Ÿ”ข
  • Subset vectors using indices, logical conditions, and set operations ๐ŸŽฏ
  • Create and work with matrices using matrix(), rbind(), and cbind() ๐Ÿ“‹
  • Perform matrix operations and basic linear algebra (%*%, t(), solve()) ๐Ÿ”ข
  • Understand document creation tools (R Markdown, LaTeX, Notebooks) ๐Ÿ“„
  • Use the apply() function for matrix computations ๐Ÿ”„
  • Practice reproducible research principles and organize projects effectively ๐Ÿ”ฌ

Getting to know each other

Poll time! ๐Ÿ—ณ๏ธ

Whatโ€™s your experience with R?

A. Never heard of it
B. Heard of it, never used it
C. Used it a few times
D. Regular user

What do you hope to learn?

A. Data analysis
B. Statistical modeling
C. Data visualization
D. All of the above!

Turn to your neighbor and discuss your answers! ๐Ÿ‘ฅ

What is R?

R: The programming language

  • R is a programming language and software environment for statistical computing and graphics ๐Ÿ“Š
  • Free and open source - anyone can use it, modify it, contribute to it ๐Ÿ†“
  • Extensible - thousands of packages for specialized tasks ๐Ÿ“ฆ
  • Community-driven - active, helpful community worldwide ๐ŸŒ
  • Reproducible - your analysis can be shared and repeated ๐Ÿ”„

Why R over other tools? ๐Ÿค”

  • More flexible than point-and-click software
  • Better for complex analyses than spreadsheets
  • Industry standard in many fields
  • Great for creating beautiful visualizations

R History and Background

  • Origins: R evolved from the S programming language developed at Bell Labs in the 1970s ๐Ÿ”ฌ

  • Creators: Ross Ihaka and Robert Gentleman at University of Auckland, New Zealand (1993) ๐Ÿ‡ณ๐Ÿ‡ฟ

  • Name: โ€œRโ€ comes from the first names of its creators (Ross and Robert) ๐Ÿ“

  • Open Source: Made freely available in 1995, managed by R Core Team ๐ŸŒ

  • Current Status: Maintained by R Foundation for Statistical Computing ๐Ÿ›๏ธ

Timeline ๐Ÿ“…

  • 1976: S language created at Bell Labs
  • 1993: R development begins
  • 1995: R made open source
  • 2000: R version 1.0.0 released
  • Today: R 4.x with thousands of packages

R Advantages and Disadvantages

Advantages โœ…

  • Free and open source ๐Ÿ’ฐ
  • Powerful graphics capabilities ๐Ÿ“Š
  • Extensive package ecosystem (19,000+ packages) ๐Ÿ“ฆ
  • Active community support ๐Ÿ‘ฅ
  • Reproducible research ๐Ÿ”„
  • Industry standard for statistics ๐Ÿ†
  • Cross-platform compatibility ๐Ÿ’ป

Disadvantages โŒ

  • Steep learning curve for beginners ๐Ÿ“ˆ
  • Memory usage can be high for large datasets ๐Ÿง 
  • Can be slow for certain operations โฑ๏ธ
  • Inconsistent syntax across packages ๐Ÿ”€
  • Not ideal for production software ๐Ÿญ

Note

Bottom line ๐Ÿ’ก R excels at statistical analysis and data visualization, but requires patience to master!

Positron: Your R workspace

Positron Interface

Four important panes (for now):

  1. Source (center): Write and edit scripts โœ๏ธ

  2. Console (bottom): Execute commands โšก

  3. Session (top-right): See your data and objects, plots ๐Ÿ“‹

  4. Explorer (left): Navigate and view files ๐Ÿ“

Letโ€™s explore Positron!

Interactive exercise

Hands-on exploration (5 minutes) โฑ๏ธ

  1. Open Positron
  2. Look at each pane - what do you see?
  3. Play BINGO
  4. If you complete a line in any direction, call BINGO!

Discuss with your neighbor: Compare answers, did you get the same ones?

More info about Positron ๐Ÿ’ก

Check out these slides from Posit: https://github.com/posit-dev/positron-workshop/tree/main/slides

R as a calculator

Basic arithmetic

Letโ€™s start simple - R can do math!

# Basic arithmetic
2 + 3
[1] 5
10 - 4
[1] 6
6 * 7
[1] 42
15 / 3
[1] 5
# More advanced operations
2^3        # Exponentiation
[1] 8
sqrt(16)   # Square root
[1] 4
log(10)    # Natural logarithm
[1] 2.302585

Try it yourself! ๐Ÿงฎ

Calculate: Whatโ€™s 23 ร— 45? Whatโ€™s the square root of 144?

Comments and good habits

# This is a comment - R ignores everything after #
# Comments help you (and others) understand your code

2 + 2  # You can also add comments at the end of lines
[1] 4
# Good habit: Comment your code!
# Your future self will thank you ๐Ÿ™

Best practice ๐Ÿ“

Always comment your code! Explain why youโ€™re doing something, not just what youโ€™re doing.

Variables: Storing information

Creating variables

Variables let us store values and reuse them:

# Assign values to variables using <-
x <- 5
y <- 10

# Now we can use them
x + y
[1] 15
x * y
[1] 50
# We can store different types of data
my_name <- "Student"
is_fun <- TRUE
# Check what's in your Environment pane! ๐Ÿ‘€
# You should see x, y, my_name, and is_fun

Variable naming rules

  • Start with a letter ๐Ÿ”ค
  • Can contain letters, numbers, dots, and underscores
  • Cannot contain spaces โŒ
  • R is case-sensitive (X and x are different!) โš ๏ธ
# Good variable names โœ…
student_age <- 20
test_score_1 <- 95
final.grade <- "A"

# Avoid these (they work, but aren't clear) โŒ
x1 <- 20
ts1 <- 95
fg <- "A"

Best practice ๐Ÿ’ก

Use descriptive names! student_age is much better than x1.

Interactive exercise: Variables

Your turn! (5 minutes) โฑ๏ธ

  1. Create a variable birth_year with your birth year
  2. Create a variable current_year with 2025
  3. Calculate your age: current_year - birth_year
  4. Store the result in a variable called my_age
  5. Check your Environment pane - what do you see? ๐Ÿ‘€

Bonus: Create variables for your favorite number and color! ๐ŸŒˆ

Share with a neighbor: What variables did you create? ๐Ÿ‘ฅ

Data types in R

The basic types

R has several basic data types:

# Numeric (numbers) ๐Ÿ”ข
age <- 25
height <- 5.8

# Character (text, always in quotes) ๐Ÿ“
name <- "Alice"
favorite_color <- "blue"

# Logical (TRUE or FALSE) โœ…โŒ
is_student <- TRUE
likes_r <- FALSE

# Check the type of a variable
class(age)
[1] "numeric"
class(name)
[1] "character"
class(is_student)
[1] "logical"

Object Classes in R

R has several basic object classes:

# Character (text)
name <- "Alice"
class(name)
[1] "character"
# Numeric (decimal numbers)
height <- 5.8
class(height)
[1] "numeric"
# Integer (whole numbers)
count <- 25L  # L forces integer
class(count)
[1] "integer"
# Logical (TRUE/FALSE)
is_student <- TRUE
class(is_student)
[1] "logical"
# Complex (imaginary numbers)
complex_num <- 3 + 2i
class(complex_num)
[1] "complex"

More on Object Classes

# Factor (categorical data)
grades <- factor(c("A", "B", "A", "C", "B"))
class(grades)
[1] "factor"
levels(grades)
[1] "A" "B" "C"
# Check object class
class(penguins$species)  # Factor
[1] "factor"
class(penguins$bill_length_mm)  # Numeric
[1] "numeric"
# Convert between classes
as.character(count)    # Convert integer to character
[1] "25"
as.numeric(is_student) # Convert logical to numeric (TRUE = 1, FALSE = 0)
[1] 1

Automatic conversion ๐Ÿ”„

R will automatically convert (coerce) data types when needed, but be careful - this can cause unexpected behavior!

Environment Management

# See all objects in your environment
ls()
 [1] "age"            "complex_num"    "count"          "favorite_color"
 [5] "fg"             "final.grade"    "grades"         "height"        
 [9] "is_fun"         "is_student"     "likes_r"        "my_name"       
[13] "name"           "student_age"    "test_score_1"   "ts1"           
[17] "x"              "x1"             "y"             
# Remove specific objects
x <- 1
y <- 2
rm(x)     # Remove x
rm(x, y)  # Remove multiple objects

# Remove all objects (be careful!)
rm(list = ls())  # Clears everything

# Check if object exists
exists("penguins")
[1] TRUE
# Get information about objects
objects()          # Same as ls()
character(0)
ls.str()          # Show structure of all objects
str(penguins)     # Structure of specific object
tibble [344 ร— 8] (S3: tbl_df/tbl/data.frame)
 $ species          : Factor w/ 3 levels "Adelie","Chinstrap",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ island           : Factor w/ 3 levels "Biscoe","Dream",..: 3 3 3 3 3 3 3 3 3 3 ...
 $ bill_length_mm   : num [1:344] 39.1 39.5 40.3 NA 36.7 39.3 38.9 39.2 34.1 42 ...
 $ bill_depth_mm    : num [1:344] 18.7 17.4 18 NA 19.3 20.6 17.8 19.6 18.1 20.2 ...
 $ flipper_length_mm: int [1:344] 181 186 195 NA 193 190 181 195 193 190 ...
 $ body_mass_g      : int [1:344] 3750 3800 3250 NA 3450 3650 3625 4675 3475 4250 ...
 $ sex              : Factor w/ 2 levels "female","male": 2 1 1 NA 1 2 1 2 NA NA ...
 $ year             : int [1:344] 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 ...
summary(penguins) # Summary of object
      species          island    bill_length_mm  bill_depth_mm  
 Adelie   :152   Biscoe   :168   Min.   :32.10   Min.   :13.10  
 Chinstrap: 68   Dream    :124   1st Qu.:39.23   1st Qu.:15.60  
 Gentoo   :124   Torgersen: 52   Median :44.45   Median :17.30  
                                 Mean   :43.92   Mean   :17.15  
                                 3rd Qu.:48.50   3rd Qu.:18.70  
                                 Max.   :59.60   Max.   :21.50  
                                 NA's   :2       NA's   :2      
 flipper_length_mm  body_mass_g       sex           year     
 Min.   :172.0     Min.   :2700   female:165   Min.   :2007  
 1st Qu.:190.0     1st Qu.:3550   male  :168   1st Qu.:2007  
 Median :197.0     Median :4050   NA's  : 11   Median :2008  
 Mean   :200.9     Mean   :4202                Mean   :2008  
 3rd Qu.:213.0     3rd Qu.:4750                3rd Qu.:2009  
 Max.   :231.0     Max.   :6300                Max.   :2009  
 NA's   :2         NA's   :2                                 

Vectors: Collections of data

Creating and using vectors

Vectors store multiple values of the same type:

# Create vectors using c() (combine function)
ages <- c(20, 21, 19, 22, 20)
names <- c("Alice", "Bob", "Charlie", "Diana")
passed <- c(TRUE, TRUE, FALSE, TRUE)

# Look at your vectors
ages
[1] 20 21 19 22 20
names
[1] "Alice"   "Bob"     "Charlie" "Diana"  
# You can do math on numeric vectors
ages + 1  # Add 1 to each age
[1] 21 22 20 23 21
mean(ages)  # Calculate the average age
[1] 20.4

Working with vectors

# Access individual elements using []
ages[1]    # First element
[1] 20
ages[3]    # Third element
[1] 19
names[2]   # Second name
[1] "Bob"
# Access multiple elements
ages[c(1, 3)]  # First and third elements
[1] 20 19
ages[1:3]      # First through third elements
[1] 20 21 19
# Useful functions for vectors
length(ages)    # How many elements?
[1] 5
sum(ages)       # Sum of all elements
[1] 102
max(ages)       # Maximum value
[1] 22
min(ages)       # Minimum value
[1] 19

More Vector Creation Methods

# Using seq() for sequences
seq(1, 10)           # 1 to 10 by 1
 [1]  1  2  3  4  5  6  7  8  9 10
seq(0, 1, by = 0.1)  # 0 to 1 by 0.1
 [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
seq(0, 1, length.out = 11)  # 11 numbers from 0 to 1
 [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
# Using rep() for repetition
rep(5, times = 3)          # Repeat 5 three times
[1] 5 5 5
rep(c(1, 2), times = 3)    # Repeat vector three times
[1] 1 2 1 2 1 2
rep(c(1, 2), each = 3)     # Repeat each element three times
[1] 1 1 1 2 2 2
# Using vector() to create empty vectors
vector("numeric", length = 5)   # Empty numeric vector
[1] 0 0 0 0 0
vector("character", length = 3) # Empty character vector
[1] "" "" ""

Special Values in R

# Missing values
NA          # Not Available (missing)
[1] NA
is.na(NA)   # Test for missing values
[1] TRUE
# Mathematical impossibilities
0/0         # NaN (Not a Number)
[1] NaN
is.nan(0/0) # Test for NaN
[1] TRUE
# Infinity
1/0         # Inf (positive infinity)
[1] Inf
-1/0        # -Inf (negative infinity)
[1] -Inf
is.infinite(1/0)  # Test for infinity
[1] TRUE
# Testing with vectors
test_vector <- c(1, 2, NA, 4, NaN, Inf)
is.na(test_vector)       # Which are NA or NaN?
[1] FALSE FALSE  TRUE FALSE  TRUE FALSE
is.finite(test_vector)   # Which are finite numbers?
[1]  TRUE  TRUE FALSE  TRUE FALSE FALSE

Vector Properties and Coercion

# Vectors can only hold one data type
# R will coerce to the most flexible type

mixed <- c(1, 2, "three", 4)  # All become character
mixed
[1] "1"     "2"     "three" "4"    
class(mixed)
[1] "character"
# Coercion hierarchy: logical < integer < numeric < character
c(TRUE, 1, 2.5, "text")  # All become character
[1] "TRUE" "1"    "2.5"  "text"
c(TRUE, 1, 2.5)          # All become numeric
[1] 1.0 1.0 2.5
c(TRUE, 1L)              # All become integer
[1] 1 1
# Explicit coercion
numbers <- c("1", "2", "3")
as.numeric(numbers)      # Convert to numeric
[1] 1 2 3
logicals <- c(TRUE, FALSE, TRUE)
as.numeric(logicals)     # TRUE = 1, FALSE = 0
[1] 1 0 1
as.character(logicals)   # Convert to character
[1] "TRUE"  "FALSE" "TRUE" 

Vector Operations and Recycling

# Vectorized operations
x <- c(1, 2, 3, 4)
y <- c(10, 20, 30, 40)

x + y    # Element-wise addition
[1] 11 22 33 44
x * y    # Element-wise multiplication
[1]  10  40  90 160
x^2      # Square each element
[1]  1  4  9 16
# Vector recycling (shorter vector repeats)
c(1, 2, 3, 4) + c(10, 20)  # c(10, 20) repeats to match length
[1] 11 22 13 24
# More useful vector functions
numbers <- c(3, 1, 4, 1, 5, 9, 2, 6)

length(numbers)    # Number of elements
[1] 8
sort(numbers)      # Sort in ascending order
[1] 1 1 2 3 4 5 6 9
sort(numbers, decreasing = TRUE)  # Sort descending
[1] 9 6 5 4 3 2 1 1
rank(numbers)      # Ranks of elements
[1] 4.0 1.5 5.0 1.5 6.0 8.0 3.0 7.0
order(numbers)     # Indices that would sort the vector
[1] 2 4 7 1 3 5 8 6
rev(numbers)       # Reverse order
[1] 6 2 9 5 1 4 1 3
unique(numbers)    # Remove duplicates
[1] 3 1 4 5 9 2 6

Advanced Vector Subsetting

scores <- c(85, 92, 78, 96, 88, 74, 91)
names(scores) <- c("Alice", "Bob", "Carol", "Dave", "Eve", "Frank", "Grace")

# Conditional subsetting
scores[scores > 90]           # Scores above 90
  Bob  Dave Grace 
   92    96    91 
scores[scores >= 80 & scores <= 95]  # Scores between 80 and 95
Alice   Bob   Eve Grace 
   85    92    88    91 
# Using which() for indices
which(scores > 90)            # Which positions have scores > 90
  Bob  Dave Grace 
    2     4     7 
which.max(scores)             # Position of maximum score
Dave 
   4 
which.min(scores)             # Position of minimum score
Frank 
    6 
# Negative indexing (exclude elements)
scores[-1]                    # Exclude first element
  Bob Carol  Dave   Eve Frank Grace 
   92    78    96    88    74    91 
scores[-c(1, 3)]             # Exclude first and third elements
  Bob  Dave   Eve Frank Grace 
   92    96    88    74    91 

Set Operations with Vectors

# Set operations
set1 <- c(1, 2, 3, 4, 5)
set2 <- c(4, 5, 6, 7, 8)

# Check membership
3 %in% set1           # Is 3 in set1?
[1] TRUE
set1 %in% set2        # Which elements of set1 are in set2?
[1] FALSE FALSE FALSE  TRUE  TRUE
# Set operations
union(set1, set2)         # Union (all unique elements)
[1] 1 2 3 4 5 6 7 8
intersect(set1, set2)     # Intersection (common elements)
[1] 4 5
setdiff(set1, set2)       # Elements in set1 but not set2
[1] 1 2 3
setequal(set1, set2)      # Are sets equal?
[1] FALSE

Interactive exercise: Vectors

Practice time! (7 minutes) โฑ๏ธ

  1. Create a vector called test_scores with these values: 85, 92, 78, 96, 88
  2. Calculate the average score using mean()
  3. Find the highest score using max()
  4. Create a vector called student_names with 5 names of your choice
  5. Try accessing the 3rd test score and the 2nd student name

Challenge: Can you find the lowest score and which position itโ€™s in? ๐Ÿ†

Matrices: 2D Data Structures

Introduction to Matrices

Matrices are 2-dimensional arrays that store data of the same type:

# Create a matrix using matrix() function
mat1 <- matrix(1:12, nrow = 3, ncol = 4)
mat1
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
# Fill by row instead of column
mat2 <- matrix(1:12, nrow = 3, ncol = 4, byrow = TRUE)
mat2
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8
[3,]    9   10   11   12
# Create matrix from vectors
vec1 <- c(1, 2, 3)
vec2 <- c(4, 5, 6)
vec3 <- c(7, 8, 9)

Matrix Creation Methods

# Using rbind() (row bind)
mat_rbind <- rbind(vec1, vec2, vec3)
mat_rbind
     [,1] [,2] [,3]
vec1    1    2    3
vec2    4    5    6
vec3    7    8    9
# Using cbind() (column bind)
mat_cbind <- cbind(vec1, vec2, vec3)
mat_cbind
     vec1 vec2 vec3
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
# Create empty matrix
empty_mat <- matrix(0, nrow = 2, ncol = 3)  # Filled with zeros
empty_mat
     [,1] [,2] [,3]
[1,]    0    0    0
[2,]    0    0    0

Matrix Attributes

# Matrix dimensions
dim(mat1)        # Dimensions (rows, columns)
[1] 3 4
nrow(mat1)       # Number of rows
[1] 3
ncol(mat1)       # Number of columns
[1] 4
length(mat1)     # Total number of elements
[1] 12
# Adding row and column names
rownames(mat1) <- c("Row1", "Row2", "Row3")
colnames(mat1) <- c("Col1", "Col2", "Col3", "Col4")
mat1
     Col1 Col2 Col3 Col4
Row1    1    4    7   10
Row2    2    5    8   11
Row3    3    6    9   12
# Check names
rownames(mat1)
[1] "Row1" "Row2" "Row3"
colnames(mat1)
[1] "Col1" "Col2" "Col3" "Col4"
dimnames(mat1)  # Both row and column names
[[1]]
[1] "Row1" "Row2" "Row3"

[[2]]
[1] "Col1" "Col2" "Col3" "Col4"

Matrix Subsetting

# Access elements using [row, column]
mat1[1, 2]       # Element in row 1, column 2
[1] 4
mat1[2, ]        # Entire row 2
Col1 Col2 Col3 Col4 
   2    5    8   11 
mat1[, 3]        # Entire column 3
Row1 Row2 Row3 
   7    8    9 
mat1[1:2, 2:4]   # Submatrix: rows 1-2, columns 2-4
     Col2 Col3 Col4
Row1    4    7   10
Row2    5    8   11
# Using names for subsetting
mat1["Row1", "Col2"]     # Using row and column names
[1] 4
mat1[c("Row1", "Row3"), ] # Multiple rows by name
     Col1 Col2 Col3 Col4
Row1    1    4    7   10
Row3    3    6    9   12
# Matrices can be treated as vectors (column-wise)
mat1[5]          # 5th element (column-wise)
[1] 5
as.vector(mat1)  # Convert matrix to vector
 [1]  1  2  3  4  5  6  7  8  9 10 11 12

Matrix Operations with apply()

# Create a sample matrix
scores <- matrix(c(85, 92, 78, 96, 88, 74, 91, 89, 76, 94, 82, 90), 
                 nrow = 3, ncol = 4)
rownames(scores) <- c("Student1", "Student2", "Student3")
colnames(scores) <- c("Math", "Science", "History", "English")
scores
         Math Science History English
Student1   85      96      91      94
Student2   92      88      89      82
Student3   78      74      76      90
# Apply functions across rows or columns
apply(scores, 1, mean)  # Row means (1 = rows)
Student1 Student2 Student3 
   91.50    87.75    79.50 
apply(scores, 2, mean)  # Column means (2 = columns)
    Math  Science  History  English 
85.00000 86.00000 85.33333 88.66667 
apply(scores, 1, max)   # Maximum score per student
Student1 Student2 Student3 
      96       92       90 
apply(scores, 2, min)   # Minimum score per subject
   Math Science History English 
     78      74      76      82 

Linear Algebra with Matrices

# Create matrices for linear algebra
A <- matrix(c(2, 1, 3, 4), nrow = 2)
B <- matrix(c(1, 2, 2, 1), nrow = 2)

A
     [,1] [,2]
[1,]    2    3
[2,]    1    4
B
     [,1] [,2]
[1,]    1    2
[2,]    2    1
# Matrix operations
A + B            # Element-wise addition
     [,1] [,2]
[1,]    3    5
[2,]    3    5
A - B            # Element-wise subtraction
     [,1] [,2]
[1,]    1    1
[2,]   -1    3
A * B            # Element-wise multiplication (NOT matrix multiplication)
     [,1] [,2]
[1,]    2    6
[2,]    2    4
A %*% B          # Matrix multiplication
     [,1] [,2]
[1,]    8    7
[2,]    9    6
# More linear algebra operations
t(A)             # Transpose
     [,1] [,2]
[1,]    2    1
[2,]    3    4
det(A)           # Determinant (for square matrices)
[1] 5
solve(A)         # Matrix inverse
     [,1] [,2]
[1,]  0.8 -0.6
[2,] -0.2  0.4
eigen(A)         # Eigenvalues and eigenvectors
eigen() decomposition
$values
[1] 5 1

$vectors
           [,1]       [,2]
[1,] -0.7071068 -0.9486833
[2,] -0.7071068  0.3162278
# Verify inverse: A %*% solve(A) should equal identity matrix
A %*% solve(A)
     [,1]          [,2]
[1,]    1 -1.110223e-16
[2,]    0  1.000000e+00

Sweeping

The sweep() function sweeps out a statistic from a matrix:

A = matrix(1:16, 4, 4, byrow=T)
A
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12
## [4,]   13   14   15   16

m = max(A)
A1 = sweep(A, MARGIN=1:2, STATS=m, FUN="-")

Sweep Example: Centering

Subtract column means:

colMeans(A)
## [1]  7  8  9 10

sweep(A, 2, colMeans(A), "-")
##      [,1] [,2] [,3] [,4]
## [1,]   -6   -6   -6   -6
## [2,]   -2   -2   -2   -2
## [3,]    2    2    2    2
## [4,]    6    6    6    6

Each column now has mean = 0!

Arrays

R supports higher-order arrays:

S = array(1:24, dim=c(4,2,3))
## , , 1
##      [,1] [,2]
## [1,]    1    5
## [2,]    2    6
## [3,]    3    7
## [4,]    4    8
## 
## , , 2
##      [,1] [,2]
## [1,]    9   13
## [2,]   10   14
## [3,]   11   15
## [4,]   12   16

Lists

A list can contain different types of elements:

x = list("California", c(1,3,5,1), 92, T, matrix(1:4, 2, 2))
x
## [[1]]
## [1] "California"
## 
## [[2]]
## [1] 1 3 5 1
## 
## [[3]]
## [1] 92
## 
## [[4]]
## [1] TRUE
## 
## [[5]]
##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4

Creating Empty Lists

x = vector("list", length=2)
x
## [[1]]
## NULL
## 
## [[2]]
## NULL

Subsetting lists uses [[]]:

x = list("California", c(1,3,5,1), 92)
x[[2]][4]
## [1] 1

List Subsetting: Important Distinction

Using [] returns a list:

x[1]
## [[1]]
## [1] "California"

Using [[]] returns the element:

x[[1]]
## [1] "California"

Recursive indexing:

x[[c(2,4)]]  # same as x[[2]][4]
## [1] 1

Exercise: Lists

Part A: Lists

  1. Create a list containing: your name, a vector of your three favorite numbers, and a 2ร—2 matrix of your choice
  2. Extract just the middle number from your vector using [[]]
  3. Add names to your list elements and practice accessing them with

Named List Elements

x = list(state="CA", co=c(1,3,5,1), loc=92)
x
## $state
## [1] "CA"
## 
## $co
## [1] 1 3 5 1
## 
## $loc
## [1] 92

Three ways to access:

x$state
x[["state"]]
x["state"]  # Returns a list!

Examining List Structure

str(x)
## List of 3
##  $ state: chr "CA"
##  $ co   : num [1:4] 1 3 5 1
##  $ loc  : num 92

Many R functions return lists:

H = hist(faithful$waiting)
names(H)
## [1] "breaks"   "counts"   "density"  "mids"     
## [5] "xname"    "equidist"

Working with Strings

x = "Hello"
y = "Bye"
z = "world"

paste(x, z)
## [1] "Hello world"

w = c(x, y)
paste(w, z, sep=" cruel ")
## [1] "Hello cruel world" "Bye cruel world"

paste(w, z, sep=" cruel ", collapse=" and ")
## [1] "Hello cruel world and Bye cruel world"

String Manipulation

Trimming strings:

substr(x, 2, 4)
## [1] "ell"

# Last 3 characters
substr(x, nchar(x)-2, nchar(x))
## [1] "llo"

Data Frames

  • Special R objects for storing data
  • Columns can be different types (unlike matrices)
  • Similar to spreadsheets
  • Variables = columns, observations = rows
x = data.frame(var1=1:4, var2=c(T,T,F,F), 
               var3=factor(c(1,1,2,1)))
x
##   var1  var2 var3
## 1    1  TRUE    1
## 2    2  TRUE    1
## 3    3 FALSE    2
## 4    4 FALSE    1

Data Frame Structure

str(x)
## 'data.frame':    4 obs. of  3 variables:
##  $ var1: int  1 2 3 4
##  $ var2: logi  TRUE TRUE FALSE FALSE
##  $ var3: Factor w/ 2 levels "1","2": 1 1 2 1

Data frames track variable types automatically!

Accessing Data Frames

Matrix-style indexing:

x[2, 3]
## [1] 1
## Levels: 1 2

x[4, 1]
## [1] 4

Using column names:

x[1:2, "var3"]
## [1] 1 1
## Levels: 1 2

x$var3[1:2]
## [1] 1 1
## Levels: 1 2

Example: Trees Dataset

head(trees, 3)
##   Girth Height Volume
## 1   8.3     70   10.3
## 2   8.6     65   10.3
## 3   8.8     63   10.2

nrow(trees)
## [1] 31

dim(trees)
## [1] 31  3

names(trees)
## [1] "Girth"  "Height" "Volume"

Summary Statistics

summary(trees)
##      Girth           Height       Volume     
##  Min.   : 8.30   Min.   :63   Min.   :10.20  
##  1st Qu.:11.05   1st Qu.:72   1st Qu.:19.40  
##  Median :12.90   Median :76   Median :24.20  
##  Mean   :13.25   Mean   :76   Mean   :30.17  
##  3rd Qu.:15.25   3rd Qu.:80   3rd Qu.:37.30  
##  Max.   :20.60   Max.   :87   Max.   :77.00

Random Number Generation

R provides functions for standard distributions:

dnorm(1, mean=0, sd=1)      # Density at x=1
## [1] 0.2419707

pnorm(1, mean=0, sd=1)      # P(X โ‰ค 1)
## [1] 0.8413447

qnorm(0.5, mean=0, sd=1)    # Median
## [1] 0

rnorm(4, mean=3, sd=1)      # Generate 4 values
## [1] 4.027 2.760 2.814 3.857

Exercise: Data Frames and Random Numbers

Part A: Data Frames

  1. Create a data frame with columns: Name (character), Age (numeric), Student (logical) for 5 people
  2. Calculate the mean age using 2 different ways, including using the mean() function.

Part B: Random Numbers

  1. Set seed to 42 and generate 100 random normal values (mean=50, sd=10)
  2. What percentage fall between 40 and 60?
  3. Create a histogram of these values

More Random Generation

Binomial distribution:

rbinom(10, size=12, prob=0.2)
##  [1] 1 4 2 1 2 1 3 4 2 3

Sampling from discrete distribution:

x = c("CA", "NE", "OR", "WA", "UT")
sample(x, 3, replace=T)
## [1] "WA" "WA" "NE"

sample(x, 3, replace=F)
## [1] "WA" "OR" "NE"

Getting Help in R (Extended)

# Multiple ways to get help
?mean          # Help for specific function
help(mean)     # Same as above
??regression   # Search for topic
help.search("regression")  # Same as ??

# See function examples
example(mean)
example(plot)

# Get help for packages
help(package = "tidyverse")

# See all functions in a package
ls("package:base")
# Other useful help functions
apropos("mean")    # Find functions containing "mean"
find("mean")       # Which packages contain "mean"
methods(mean)      # See all methods for generic function

Best Practice ๐Ÿ“

Use <- for assignment. Itโ€™s the R convention and makes your code more readable!

Keyboard shortcut: Alt + - (Windows) or Option + - (Mac)

# Why <- is preferred over =
# = can be confused with == (equality test)
# <- clearly shows direction of assignment
# Some contexts require <-

# This works differently:
mean(x = c(1, 2, 3))  # = assigns argument
[1] 2
mean(x <- c(1, 2, 3)) # <- assigns to environment AND passes to function
[1] 2

Case Sensitivity in R

# R is case sensitive!
x <- 5
X <- 10

x  # lowercase
[1] 5
X  # uppercase - different variable!
[1] 10
# Function names are also case sensitive
mean(c(1, 2, 3))  # works
[1] 2
Mean(c(1, 2, 3))  # Error! 
Error in Mean(c(1, 2, 3)): could not find function "Mean"
# Common case sensitivity mistakes
data <- c(5, 10, 15)
mean(Data)  # Error - 'Data' doesn't exist
Error: object 'Data' not found
mean(data)  # Works - 'data' exists
[1] 10
# Even dataset names are case sensitive
head(Penguins)  # Error
Error: object 'Penguins' not found
head(penguins)  # Works
# A tibble: 6 ร— 8
  species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
  <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
1 Adelie  Torgersen           39.1          18.7               181        3750
2 Adelie  Torgersen           39.5          17.4               186        3800
3 Adelie  Torgersen           40.3          18                 195        3250
4 Adelie  Torgersen           NA            NA                  NA          NA
5 Adelie  Torgersen           36.7          19.3               193        3450
6 Adelie  Torgersen           39.3          20.6               190        3650
# โ„น 2 more variables: sex <fct>, year <int>

Common mistakes & fixes

Troubleshooting

  • Typos in function names: maen() instead of mean() โŒ
    • Solution: Use tab-completion! โœ…
  • Missing parentheses: mean instead of mean() โŒ
    • Solution: Functions need () โœ…
  • Forgetting quotes: name <- Alice instead of name <- "Alice" โŒ
    • Solution: Text needs quotes โœ…
  • Case sensitivity: Mean() instead of mean() โŒ
    • Solution: R is case-sensitive! โœ…

Tip

Donโ€™t worry about making mistakes - theyโ€™re part of learning! Read error messages carefully. ๐Ÿง 

Error messages: Your friends!

# This will cause an error
mean(Ages)  # We created 'ages', not 'Ages'
Error: object 'Ages' not found
# Fix it:
mean(ages)
[1] 20.4

Reading error messages ๐Ÿ”

  1. Donโ€™t panic! Errors are normal ๐Ÿ˜Œ
  2. Read the message - it often tells you whatโ€™s wrong ๐Ÿ“–
  3. Check for typos - most common cause โœ๏ธ
  4. Google the error if youโ€™re stuck ๐Ÿ”

Hands-on challenge

Mini project

Your mission (15 minutes) ๐ŸŽฏ

Create a simple analysis of your class!

  1. Create vectors for: student_names, birth_months, favorite_numbers. Assign 50 random numbers to months (from 1 to 12), 50 random numbers from 0 to 100 in the favorite numbers column, and use the package randomNames to generate 50 names. Create a data frame with all three columns.
  2. Calculate some summaries (mean, max, min of favorite numbers)
  3. Save everything in an R script called โ€œclass_analysis.Rโ€
  4. Add comments explaining each step ๐Ÿ“

Bonus: Try to find out which birth month is most common using table() ๐Ÿ—“๏ธ

Work in pairs and help each other! ๐Ÿ‘ฅ

Document Creation Tools

LaTeX Integration in Quarto

Quarto has built-in support for LaTeX typesetting:

  • LaTeX: Professional typesetting system for technical documents ๐Ÿ“„
  • Math Equations: Beautiful mathematical notation ๐Ÿ“
  • Bibliography: Automatic citation management ๐Ÿ“š
  • Cross-references: Automatic numbering and linking ๐Ÿ”—
% Example LaTeX equation in Quarto
$$\bar{x} = \frac{1}{n}\sum_{i=1}^{n} x_i$$

% Inline math: The mean is $\bar{x}$

Quarto: Reproducible Documents

Quarto combines code, text, and output in one document:

  • Code Chunks: Executable R code within text ๐Ÿ’ป
  • Multiple Outputs: HTML, PDF, Word, presentations ๐Ÿ“Š
  • Dynamic: Results update when code changes ๐Ÿ”„
  • Reproducible: Anyone can recreate your analysis ๐Ÿ”
# My Analysis


::: {.cell}

```{.r .cell-code}
# This code will run and show results
summary(penguins)
```

::: {.cell-output .cell-output-stdout}

```
      species          island    bill_length_mm  bill_depth_mm  
 Adelie   :152   Biscoe   :168   Min.   :32.10   Min.   :13.10  
 Chinstrap: 68   Dream    :124   1st Qu.:39.23   1st Qu.:15.60  
 Gentoo   :124   Torgersen: 52   Median :44.45   Median :17.30  
                                 Mean   :43.92   Mean   :17.15  
                                 3rd Qu.:48.50   3rd Qu.:18.70  
                                 Max.   :59.60   Max.   :21.50  
                                 NA's   :2       NA's   :2      
 flipper_length_mm  body_mass_g       sex           year     
 Min.   :172.0     Min.   :2700   female:165   Min.   :2007  
 1st Qu.:190.0     1st Qu.:3550   male  :168   1st Qu.:2007  
 Median :197.0     Median :4050   NA's  : 11   Median :2008  
 Mean   :200.9     Mean   :4202                Mean   :2008  
 3rd Qu.:213.0     3rd Qu.:4750                3rd Qu.:2009  
 Max.   :231.0     Max.   :6300                Max.   :2009  
 NA's   :2         NA's   :2                                 
```


:::
:::


The mean bill length is 43.9219298 mm.

What weโ€™ve learned up until today

Learning summary

โœ… Positron Interface: Four panes and their purposes ๐Ÿ–ฅ๏ธ
โœ… R as Calculator: Basic and advanced operations ๐Ÿงฎ
โœ… Variables: Storing and reusing information ๐Ÿ“Š
โœ… Data Types: Numeric, character, logical ๐Ÿ”ข๐Ÿ“โœ…
โœ… Vectors: Collections of data ๐Ÿ“ˆ
โœ… Functions: Getting help and using built-in functions ๐Ÿ› ๏ธ
โœ… Packages: Extending Rโ€™s capabilities ๐Ÿ“ฆ
โœ… Scripts & Quarto: Organizing your work ๐Ÿ“

Looking ahead

Next steps

Next class weโ€™ll cover:

  • Data frames in detail ๐Ÿ“Š
  • Reading data from files (CSV, Excel) ๐Ÿ“‚
  • More data exploration techniques ๐Ÿ”
  • Introduction to data visualization ๐Ÿ“ˆ
  • More on reproducible reports with Quarto ๐Ÿ“„

Resources for continued learning

Final activity

Reflection time ๐Ÿค”

Think-pair-share (5 minutes) โฑ๏ธ

Think (1 min): Name one thing you learned about R that you didnโ€™t know before.

Pair (2 min): Share with your neighbor and listen to their surprise ๐Ÿ‘ฅ

Share (2 min): Share it on Ed Discussion ๐Ÿ—ฃ๏ธ

Remember: Every expert was once a beginner! ๐ŸŒฑ

Questions?

Letโ€™s talk! ๐Ÿ’ฌ

Office Hours: Tu and Th after lecture ๐Ÿ•
Email: macordob@ucsc.edu ๐Ÿ“ง
Course Website: Course URL ๐ŸŒ

Thank you! and great job today! ๐ŸŽ‰

Next class: More data wrangling and visualization ๐Ÿ“Š

Keep exploring and have fun with R! ๐Ÿš€