1 Course purpose

This is a 60-minute introductory laboratory in R and RStudio. The aim is not merely to learn commands, but to understand the computational ideas that support statistical work in R.

The lecture follows the workflow

\[\boxed{\text{Create/Read} \rightarrow \text{Inspect} \rightarrow \text{Manipulate} \rightarrow \text{Summarize} \rightarrow \text{Visualize} \rightarrow \text{Save}}\]

The emphasis is on base R, so that students first understand vectors, indexing, functions, data frames, and graphics before moving to packages such as dplyr and ggplot2.

1.1 Learning outcomes

By the end of the session, students should be able to:

  1. use R as a scientific calculator;
  2. create and inspect R objects;
  3. distinguish numeric, character, logical, and factor variables;
  4. construct vectors, matrices, and arrays;
  5. perform indexing and vectorized operations;
  6. recognize and handle NA;
  7. generate sequences and random observations;
  8. write simple functions and conditional statements;
  9. use for and while loops;
  10. construct and customize base-R graphics;
  11. place several graphs in one plotting device;
  12. import CSV and TXT data;
  13. calculate descriptive statistics;
  14. construct bar plots, pie charts, histograms, boxplots, and scatterplots;
  15. manipulate data frames and export results.

1.2 Suggested 60-minute schedule

Time Topic
0–3 min RStudio, workspace, help
3–9 min Arithmetic, objects, data types, logic
9–14 min Vectors, matrices, arrays
14–20 min Indexing, vectorization, missing values
20–24 min Sequences and random numbers
24–29 min Functions and decisions
29–34 min Loops and simulation
34–43 min Graphics
43–47 min Reading and inspecting data
47–55 min Descriptive statistics and statistical plots
55–60 min Data-frame manipulation and saving

2 0. RStudio, workspace, and help

R is a programming language and environment for statistical computing. RStudio is an integrated development environment (IDE) for working with R.

The four main RStudio regions are:

  • Source: scripts and documents;
  • Console: commands are executed here;
  • Environment/History: current objects and command history;
  • Files/Plots/Packages/Help: files, graphics, packages, and documentation.

A reproducible analysis should live primarily in the script/document, not only in the Console.

getwd()                 # Current working directory
#> [1] "/Users/buddhanandabanerjee/Downloads/Stat_Demo_RStudio_60min"
ls()                    # Objects currently in memory
#> character(0)

getwd() means get working directory. When R reads or writes a file using only a filename, this directory is the default location.

To clear the interactive workspace:

rm(list = ls())

This command is not executed while rendering this document because later chunks depend on objects created earlier.

2.1 R’s help system

?mean
help(mean)
example(mean)

A strong R user does not memorize every function argument. Instead, they know how to find and interpret documentation.

3 1. Arithmetic, objects, types, and logic

3.1 1.1 R as a calculator

10 + 5
#> [1] 15
10 - 5
#> [1] 5
10 * 5
#> [1] 50
10 / 5
#> [1] 2
2^5
#> [1] 32
17 %% 5
#> [1] 2
17 %/% 5
#> [1] 3

The operators have the following meanings:

Operator Meaning
+, - addition, subtraction
*, / multiplication, division
^ exponentiation
%% remainder
%/% integer division

R follows the usual order of mathematical operations.

2 + 3 * 4
#> [1] 14
(2 + 3) * 4
#> [1] 20

3.2 1.2 Objects and assignment

An object is a named location in which R stores information.

x <- 10
y <- 3

x + y
#> [1] 13
x * y
#> [1] 30
x^y
#> [1] 1000

The conventional assignment operator is <-.

Some common mathematical functions are:

sqrt(25)
#> [1] 5
log(10)
#> [1] 2.302585
exp(1)
#> [1] 2.718282
sin(pi / 2)
#> [1] 1
abs(-7)
#> [1] 7

3.3 1.3 Basic data types

x <- 10
course <- "R Programming"
passed <- TRUE

class(x)
#> [1] "numeric"
class(course)
#> [1] "character"
class(passed)
#> [1] "logical"
typeof(x)
#> [1] "double"
typeof(course)
#> [1] "character"
typeof(passed)
#> [1] "logical"

Three fundamental types are:

  • numeric: measurements or numbers;
  • character: text;
  • logical: TRUE or FALSE.

3.4 1.4 Factors and categorical variables

A factor represents categorical data.

grade <- factor(c("A", "B", "A", "C", "B"))

grade
#> [1] A B A C B
#> Levels: A B C
levels(grade)
#> [1] "A" "B" "C"
table(grade)
#> grade
#> A B C 
#> 2 2 1

levels() shows the possible categories. table() counts the observations in each category.

3.5 1.5 Comparisons and logical operators

x <- 10

x > 5
#> [1] TRUE
x < 5
#> [1] FALSE
x == 10
#> [1] TRUE
x != 10
#> [1] FALSE
x >= 10
#> [1] TRUE
x <= 10
#> [1] TRUE

Do not confuse:

  • <- : assignment;
  • == : equality comparison.

Logical statements can be combined:

(x > 5) & (x < 20)      # AND
#> [1] TRUE
(x < 5) | (x == 10)     # OR
#> [1] TRUE
!(x > 5)                # NOT
#> [1] FALSE

4 2. Vectors, matrices, and arrays

R is fundamentally vector oriented. Many calculations that require explicit loops in other languages can be applied directly to entire vectors in R.

4.1 2.1 Vectors

v <- c(10, 20, 30, 40, 50)

v
#> [1] 10 20 30 40 50
length(v)
#> [1] 5
class(v)
#> [1] "numeric"

c() means combine or concatenate. A vector is a one-dimensional collection of values.

4.2 2.2 Matrices

A matrix is a two-dimensional rectangular structure.

A <- matrix(1:12, nrow = 3, ncol = 4)

A
#>      [,1] [,2] [,3] [,4]
#> [1,]    1    4    7   10
#> [2,]    2    5    8   11
#> [3,]    3    6    9   12
dim(A)
#> [1] 3 4

By default R fills matrices column by column.

B <- matrix(1:12, nrow = 3, ncol = 4, byrow = TRUE)
B
#>      [,1] [,2] [,3] [,4]
#> [1,]    1    2    3    4
#> [2,]    5    6    7    8
#> [3,]    9   10   11   12

4.3 2.3 Arrays

An array generalizes the matrix to more than two dimensions.

X <- array(1:24, dim = c(3, 4, 2))

X
#> , , 1
#> 
#>      [,1] [,2] [,3] [,4]
#> [1,]    1    4    7   10
#> [2,]    2    5    8   11
#> [3,]    3    6    9   12
#> 
#> , , 2
#> 
#>      [,1] [,2] [,3] [,4]
#> [1,]   13   16   19   22
#> [2,]   14   17   20   23
#> [3,]   15   18   21   24
dim(X)
#> [1] 3 4 2

Thus:

\[\text{vector: 1D},\qquad \text{matrix: 2D},\qquad \text{array: higher-dimensional}.\]

5 3. Indexing, vectorization, missing values, and sorting

5.1 3.1 Vector indexing

Square brackets select elements.

v[1]
#> [1] 10
v[2:4]
#> [1] 20 30 40
v[-1]
#> [1] 20 30 40 50
v[c(1, 3, 5)]
#> [1] 10 30 50
v[v > 25]
#> [1] 30 40 50

The last expression uses logical indexing: R keeps values for which the condition is TRUE.

5.2 3.2 Matrix indexing

The standard matrix convention is

\[\texttt{A[row, column]}.\]

A[2, 3]
#> [1] 8
A[1, ]
#> [1]  1  4  7 10
A[, 2]
#> [1] 4 5 6

A blank row or column index means “all”.

5.3 3.3 Vectorized operations

z <- 1:4

z + 10
#> [1] 11 12 13 14
z * 2
#> [1] 2 4 6 8
z^2
#> [1]  1  4  9 16
sqrt(z)
#> [1] 1.000000 1.414214 1.732051 2.000000

These operations act on every element without an explicit loop. This is called vectorization.

5.4 3.4 Matrix operations

M1 <- matrix(c(1, 2, 3, 4), nrow = 2)
M2 <- matrix(c(5, 6, 7, 8), nrow = 2)

M1 * M2
#>      [,1] [,2]
#> [1,]    5   21
#> [2,]   12   32
M1 %*% M2
#>      [,1] [,2]
#> [1,]   23   31
#> [2,]   34   46
t(M1)
#>      [,1] [,2]
#> [1,]    1    2
#> [2,]    3    4

The distinction is essential:

  • * gives elementwise multiplication;
  • %*% gives matrix multiplication;
  • t() gives the transpose.

5.5 3.5 Missing observations

R represents a missing observation by NA.

x_missing <- c(10, 12, NA, 15, 18)

mean(x_missing)
#> [1] NA
mean(x_missing, na.rm = TRUE)
#> [1] 13.75
is.na(x_missing)
#> [1] FALSE FALSE  TRUE FALSE FALSE
sum(is.na(x_missing))
#> [1] 1

na.rm = TRUE means remove NA values for this calculation.

Statistical caution: computationally ignoring missing observations is not automatically an appropriate missing-data analysis. This example demonstrates syntax only.

5.6 3.6 Sorting

x_sort <- c(8, 3, 10, 2, 7)

sort(x_sort)
#> [1]  2  3  7  8 10
sort(x_sort, decreasing = TRUE)
#> [1] 10  8  7  3  2
order(x_sort)
#> [1] 4 2 5 1 3
x_sort[order(x_sort)]
#> [1]  2  3  7  8 10

sort() returns sorted values. order() returns the positions needed to place values in order. The latter is especially useful for sorting data frames.

6 4. Sequences, repetition, and random numbers

6.1 4.1 Sequences

1:10
#>  [1]  1  2  3  4  5  6  7  8  9 10
10:1
#>  [1] 10  9  8  7  6  5  4  3  2  1
seq(0, 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 = 6)
#> [1] 0.0 0.2 0.4 0.6 0.8 1.0

Use : for simple integer sequences and seq() when more control is needed.

6.2 4.2 Repetition

rep(5, 4)
#> [1] 5 5 5 5
rep(c(1, 2), times = 3)
#> [1] 1 2 1 2 1 2
rep(c("A", "B"), each = 3)
#> [1] "A" "A" "A" "B" "B" "B"

times repeats the whole pattern; each repeats each element.

6.3 4.3 Random-number generation and reproducibility

set.seed(123)

rnorm(5)
#> [1] -0.56047565 -0.23017749  1.55870831  0.07050839  0.12928774
runif(5)
#> [1] 0.9568333 0.4533342 0.6775706 0.5726334 0.1029247
rbinom(10, size = 1, prob = 0.5)
#>  [1] 1 0 0 0 1 1 1 1 1 1

set.seed() makes pseudo-random simulation reproducible.

  • rnorm() generates normal observations;
  • runif() generates uniform observations;
  • rbinom() generates binomial observations.

7 5. Functions and decisions

7.1 5.1 Built-in functions

u <- c(4, 7, 2, 9, 5)

mean(u)
#> [1] 5.4
median(u)
#> [1] 5
sd(u)
#> [1] 2.701851
var(u)
#> [1] 7.3
min(u)
#> [1] 2
max(u)
#> [1] 9

7.2 5.2 User-defined functions

A function packages a calculation so it can be reused.

square <- function(x) {
  return(x^2)
}

square(5)
#> [1] 25
square(c(1, 2, 3, 4))
#> [1]  1  4  9 16

A statistical example:

cv <- function(x) {
  return(sd(x) / mean(x))
}

cv(c(12, 15, 18, 20, 25))
#> [1] 0.274986

The coefficient of variation is

\[CV=\frac{s}{\bar{x}},\]

when this quantity is meaningful for the measurement scale.

7.3 5.3 if and else

score <- 75

if (score >= 50) {
  print("Pass")
} else {
  print("Fail")
}
#> [1] "Pass"

The program evaluates a logical condition and chooses one branch.

8 6. Loops and a small simulation

8.1 6.1 for loop

squares <- numeric(10)

for (i in 1:10) {
  squares[i] <- i^2
}

squares
#>  [1]   1   4   9  16  25  36  49  64  81 100

numeric(10) pre-allocates the result vector. Pre-allocation is preferable to repeatedly growing an object inside a loop.

8.2 6.2 while loop

i <- 1

while (i <= 5) {
  print(i)
  i <- i + 1
}
#> [1] 1
#> [1] 2
#> [1] 3
#> [1] 4
#> [1] 5

A while loop continues while its logical condition remains true.

8.3 6.3 Simulation: sampling distribution of the mean

set.seed(123)

sample_means <- numeric(200)

for (i in 1:200) {
  sample_means[i] <- mean(rnorm(30))
}

summary(sample_means)
#>      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
#> -0.479357 -0.108097  0.016034  0.005272  0.111283  0.346561

Each iteration generates a sample of size 30 from \(N(0,1)\) and records its mean. The resulting 200 means approximate the sampling distribution of the sample mean.

hist(
  sample_means,
  col = "skyblue",
  border = "white",
  main = "Sampling Distribution of the Mean",
  xlab = "Sample mean"
)

This is the first important bridge from programming to statistical simulation.

9 7. Graphics: basic to modern base R

xgrid <- seq(-2 * pi, 2 * pi, length.out = 500)
y_sin <- sin(xgrid)
y_cos <- cos(xgrid)

9.1 7.1 Basic line plot

plot(
  xgrid, y_sin,
  type = "l",
  main = "Sine Curve",
  xlab = "x",
  ylab = "sin(x)"
)

type = "l" requests a line plot.

9.2 7.2 Colour, line width, and line style

plot(
  xgrid, y_sin,
  type = "l",
  col = "royalblue3",
  lwd = 3,
  lty = 1,
  main = "Styled Sine Curve",
  xlab = "x",
  ylab = "sin(x)"
)

Useful arguments:

  • col: colour;
  • lwd: line width;
  • lty: line type;
  • pch: plotting symbol;
  • cex: relative point/text size.

9.3 7.3 More than one curve on the same graph

plot(
  xgrid, y_sin,
  type = "l",
  col = "royalblue3",
  lwd = 3,
  ylim = c(-1.1, 1.1),
  xlab = "x",
  ylab = "Function value",
  main = "Sine and Cosine"
)

lines(xgrid, y_cos, col = "tomato3", lwd = 3, lty = 2)

legend(
  "topright",
  legend = c("sin(x)", "cos(x)"),
  col = c("royalblue3", "tomato3"),
  lwd = 3,
  lty = c(1, 2),
  bty = "n"
)

Remember:

plot() starts a graph; lines() and points() add to the current graph.

9.4 7.4 A cleaner modern base-R style

plot(
  xgrid, y_sin,
  type = "n",
  ylim = c(-1.1, 1.1),
  xlab = "x",
  ylab = "Function value",
  main = "Modern Base-R Style"
)

grid(col = "grey88")

lines(xgrid, y_sin, col = "#0072B2", lwd = 3)
lines(xgrid, y_cos, col = "#D55E00", lwd = 3, lty = 2)

abline(h = 0, col = "grey50", lty = 3)

legend(
  "topright",
  c("Sine", "Cosine"),
  col = c("#0072B2", "#D55E00"),
  lwd = 3,
  lty = c(1, 2),
  bty = "n"
)

type = "n" creates the plotting region without drawing the observations. This lets us draw the grid first and then place the curves above it.

9.5 7.5 Transparent shading

plot(
  xgrid, y_sin,
  type = "n",
  ylim = c(-1.1, 1.1),
  xlab = "x",
  ylab = "sin(x)",
  main = "Transparent Shading"
)

grid(col = "grey90")

polygon(
  c(xgrid, rev(xgrid)),
  c(y_sin, rep(0, length(xgrid))),
  col = adjustcolor("royalblue3", alpha.f = 0.20),
  border = NA
)

lines(xgrid, y_sin, col = "royalblue3", lwd = 3)
abline(h = 0, col = "grey40", lty = 2)

9.6 7.6 Points and lines

xsmall <- seq(0, 2 * pi, length.out = 20)

plot(
  xsmall, sin(xsmall),
  type = "b",
  pch = 19,
  col = "royalblue3",
  lwd = 2,
  cex = 1.2,
  xlab = "x",
  ylab = "sin(x)",
  main = "Points and Lines"
)

type = "b" means both points and lines.

9.7 7.7 Several graphs in one plotting device

par(mfrow = c(2, 2))

plot(xgrid, y_sin, type = "l", col = "#0072B2",
     lwd = 3, main = "Sine")

plot(xgrid, y_cos, type = "l", col = "#D55E00",
     lwd = 3, main = "Cosine")

plot(xgrid, y_sin^2, type = "l", col = "#009E73",
     lwd = 3, main = expression(sin^2(x)))

plot(xgrid, y_sin * y_cos, type = "l", col = "#CC79A7",
     lwd = 3, main = "sin(x) cos(x)")

par(mfrow = c(1, 1))

par(mfrow = c(2,2)) divides the plotting device into four frames.

9.8 7.8 Saving graphics

The general pattern is:

\[\boxed{\text{open device} \rightarrow \text{draw graph} \rightarrow \texttt{dev.off()}}\]

png(
  "modern_sine_cosine.png",
  width = 1800,
  height = 1200,
  res = 200
)

plot(xgrid, y_sin, type = "l",
     col = "#0072B2", lwd = 4,
     xlab = "x", ylab = "Function value")

lines(xgrid, y_cos, col = "#D55E00", lwd = 4, lty = 2)

dev.off()

For a vector PDF:

pdf("modern_sine_cosine.pdf", width = 8, height = 6)

plot(xgrid, y_sin, type = "l",
     col = "#0072B2", lwd = 3)

lines(xgrid, y_cos, col = "#D55E00", lwd = 3, lty = 2)

dev.off()

10 8. Reading CSV and TXT data

This section uses the teaching files:

  • student_statistics_demo.csv
  • student_statistics_demo.txt

Place them in the same working directory as this document.

10.1 8.1 Read CSV

students <- read.csv("student_statistics_demo.csv")

10.2 8.2 Inspect before analysing

head(students)
tail(students)

dim(students)
nrow(students)
ncol(students)

names(students)
str(students)
summary(students)

These commands answer different questions:

Command Question
head() What do the first observations look like?
dim() How large is the dataset?
names() What variables are available?
str() What data types were imported?
summary() What is the first descriptive overview?

10.3 8.3 Read TXT

students_txt <- read.table(
  "student_statistics_demo.txt",
  header = TRUE,
  sep = "\t"
)

head(students_txt)

10.4 8.4 Missing-value audit

sum(is.na(students))
colSums(is.na(students))

A basic data analysis should inspect missingness before computing final summaries.

11 9. Descriptive statistics and statistical graphics

The code in this section assumes that students has been imported in Section 8.

11.1 9.1 Numerical summaries

mean(students$Score)
median(students$Score)
sd(students$Score)
var(students$Score)
range(students$Score)
quantile(students$Score)

These describe different aspects of a quantitative distribution:

  • mean and median: location;
  • variance and standard deviation: dispersion;
  • range and quantiles: spread and position.

A compact named summary:

score_summary <- c(
  N = length(students$Score),
  Mean = mean(students$Score),
  Median = median(students$Score),
  SD = sd(students$Score),
  Minimum = min(students$Score),
  Q1 = unname(quantile(students$Score, 0.25)),
  Q3 = unname(quantile(students$Score, 0.75)),
  Maximum = max(students$Score)
)

score_summary

11.2 9.2 Frequency tables

department_frequency <- table(students$Department)
grade_frequency <- table(students$Grade)

department_frequency
grade_frequency

prop.table(department_frequency)

table() returns counts; prop.table() converts them to proportions.

11.3 9.3 Bar plot

A bar plot represents categorical frequencies.

barplot(
  department_frequency,
  main = "Students by Department",
  xlab = "Department",
  ylab = "Frequency",
  col = c("#0072B2", "#D55E00", "#009E73", "#CC79A7"),
  border = NA,
  las = 2
)

11.4 9.4 Pie chart

pie(
  grade_frequency,
  main = "Distribution of Grades",
  col = rainbow(length(grade_frequency))
)

Pie charts emphasize part-to-whole composition. Bar plots are generally easier when precise category comparisons are important.

11.5 9.5 Histogram

A histogram displays the distribution of a quantitative variable using numerical bins.

hist(
  students$Score,
  breaks = 12,
  col = "#56B4E9",
  border = "white",
  main = "Distribution of Student Scores",
  xlab = "Score",
  ylab = "Frequency"
)

A histogram is fundamentally different from a bar plot: its horizontal axis represents intervals of a quantitative scale.

11.6 9.6 Boxplot

boxplot(
  students$Score,
  col = "#009E73",
  main = "Student Scores",
  ylab = "Score"
)

A boxplot summarizes the median, quartiles, spread, and possible outliers.

Grouped boxplots compare distributions:

boxplot(
  Score ~ Department,
  data = students,
  col = c("#0072B2", "#D55E00", "#009E73", "#CC79A7"),
  main = "Scores by Department",
  xlab = "Department",
  ylab = "Score",
  las = 2
)

11.7 9.7 Scatterplot and fitted line

plot(
  students$StudyHours,
  students$Score,
  pch = 19,
  col = adjustcolor("#0072B2", alpha.f = 0.60),
  xlab = "Study hours",
  ylab = "Score",
  main = "Study Hours versus Score"
)

fit <- lm(Score ~ StudyHours, data = students)
abline(fit, col = "#D55E00", lwd = 3)

summary(fit)

A scatterplot is appropriate for examining the relationship between two quantitative variables. The fitted line is included only as an introductory demonstration; regression theory belongs in a later lecture.

11.8 9.8 Grouped summaries

aggregate(Score ~ Department, data = students, FUN = mean)
aggregate(Score ~ Department, data = students, FUN = sd)

11.9 9.9 Four descriptive plots on one page

par(mfrow = c(2, 2))

barplot(department_frequency,
        col = c("#0072B2", "#D55E00", "#009E73", "#CC79A7"),
        border = NA, main = "Department", las = 2)

pie(grade_frequency,
    col = rainbow(length(grade_frequency)),
    main = "Grades")

hist(students$Score,
     breaks = 12, col = "#56B4E9", border = "white",
     main = "Scores", xlab = "Score")

boxplot(students$Score,
        col = "#009E73", main = "Scores", ylab = "Score")

par(mfrow = c(1, 1))

12 10. Data frames: select, transform, sort, and save

A data frame is a rectangular statistical structure:

\[\boxed{\text{rows = observations},\qquad \text{columns = variables}.}\]

12.1 10.1 Selecting data

class(students)
students$Score

students[1, ]
students[1:5, c("ID", "Department", "Score")]

12.2 10.2 Conditional selection

high_scores <- students[students$Score >= 85, ]

head(high_scores)
nrow(high_scores)

The expression students$Score >= 85 produces a logical vector, which is used to retain matching rows.

12.3 10.3 Creating categorical variables with ifelse()

students$Result <- ifelse(
  students$Score >= 50,
  "Pass",
  "Fail"
)

students$Performance <- ifelse(
  students$Score >= 80,
  "High",
  "Regular"
)

table(students$Result)
table(students$Performance)

ifelse() is vectorized: it applies the condition to every observation.

12.4 10.4 Creating a numerical variable

students$BMI <- students$Weight_kg /
                (students$Height_cm / 100)^2

summary(students$BMI)

This demonstrates how new variables are derived from existing columns.

12.5 10.5 Sorting a data frame

students_sorted <- students[
  order(students$Score, decreasing = TRUE),
]

students_sorted[
  1:5,
  c("ID", "Department", "Score")
]

12.6 10.6 Exporting processed data

write.csv(
  students,
  "student_statistics_demo_processed.csv",
  row.names = FALSE
)

write.csv(
  high_scores,
  "high_scoring_students.csv",
  row.names = FALSE
)

row.names = FALSE avoids writing R’s internal row labels as an unwanted extra variable.

13 11. Two-minute integrated closing exercise

Once the dataset has been imported, ask students to solve these without introducing any new commands.

13.0.1 Question 1: What are the mean and standard deviation of Score?

mean(students$Score)
sd(students$Score)

13.0.2 Question 2: How many students belong to each department?

table(students$Department)

13.0.3 Question 3: Compare departments graphically.

boxplot(
  Score ~ Department,
  data = students,
  col = c("#0072B2", "#D55E00", "#009E73", "#CC79A7"),
  main = "Score by Department",
  las = 2
)

13.0.4 Question 4: Find students with Score at least 90.

excellent_students <- students[students$Score >= 90, ]
head(excellent_students)

13.0.5 Question 5: Save the result.

write.csv(
  excellent_students,
  "excellent_students.csv",
  row.names = FALSE
)

14 12. Summary: the statistical-computing mindset

The important lesson is not a list of commands. It is a workflow.

\[\boxed{ \text{Create/Read} \rightarrow \text{Inspect} \rightarrow \text{Manipulate} \rightarrow \text{Summarize} \rightarrow \text{Visualize} \rightarrow \text{Save} }\]

Students should leave the lecture understanding these core ideas:

  • R stores information in objects.
  • Vectors are central to R’s design.
  • Logical conditions and indexing provide a concise language for data selection.
  • Vectorization often replaces explicit loops.
  • Functions package reusable calculations.
  • Simulation links programming with probability and statistics.
  • Graphics should communicate the statistical structure of data.
  • Data should be inspected before being analyzed.
  • Reproducible code is part of the statistical analysis itself.

15 13. Natural next topics

A second R lecture can naturally introduce:

  • probability distributions through d*, p*, q*, and r*;
  • z, t, chi-square, and F inference;
  • confidence intervals and hypothesis testing;
  • statistical power;
  • goodness-of-fit;
  • ggplot2;
  • dplyr;
  • regression and classification.

End of tutorial