JSTAcademy
0 XP
Dashboard
Crash Courses
Statistical Analysis: Summaries, Distributions & Tests
20 min
PhD+185 XP
Crash Courses · PhD

Statistical Analysis: Summaries, Distributions & Tests

Perform the statistical analysis that R is known for — descriptive stats, probability distributions, t-tests, chi-square, ANOVA, and correlation.
20 min read+185 XP on completionCert: R Crash Course
Tap any word in the text below to start reading from there.

Statistical Analysis: Summaries, Distributions & Tests

Comprehensive Descriptive Statistics

# R's built-in summary
data(mtcars)
summary(mtcars)  # min, Q1, median, mean, Q3, max for each column

# Custom function for more detail
describe_var <- function(x, name = deparse(substitute(x))) {
  cat(sprintf("--- %s ---\n", name))
  cat(sprintf("N: %d | Missing: %d\n", sum(!is.na(x)), sum(is.na(x))))
  cat(sprintf("Mean: %.3f | Median: %.3f\n", mean(x, na.rm=T), median(x, na.rm=T)))
  cat(sprintf("SD: %.3f | IQR: %.3f\n", sd(x, na.rm=T), IQR(x, na.rm=T)))
  cat(sprintf("Min: %.3f | Max: %.3f\n", min(x, na.rm=T), max(x, na.rm=T)))
  q <- quantile(x, c(0.25, 0.75, 0.90, 0.95), na.rm=T)
  cat(sprintf("P25: %.3f | P75: %.3f | P90: %.3f | P95: %.3f\n", q[1], q[2], q[3], q[4]))
}

describe_var(mtcars$mpg)

---

Probability Distributions

R follows a consistent naming convention for distributions:

  • d = density (PDF): dnorm(x)
  • p = cumulative probability (CDF): pnorm(x)
  • q = quantile (inverse CDF): qnorm(p)
  • r = random sample: rnorm(n)
# Normal distribution
dnorm(0)              # density at 0: 0.3989
pnorm(1.96)           # P(Z <= 1.96) = 0.975 (95th percentile)
qnorm(0.975)          # 1.96 — the value at 97.5th percentile
rnorm(5, mean=100, sd=15)  # 5 random IQ-like scores

# What proportion of a N(100, 15) distribution is above 130?
pnorm(130, mean=100, sd=15, lower.tail=FALSE)  # 0.02275

# Binomial distribution
# P(X = 3) when n=10 trials, p=0.3 success probability
dbinom(3, size=10, prob=0.3)  # 0.2668
# P(X <= 3)
pbinom(3, size=10, prob=0.3)  # 0.6496

---

One-Sample and Two-Sample t-tests

# One-sample: is the mean mpg different from 20?
t.test(mtcars$mpg, mu = 20)
# Output shows: t statistic, df, p-value, 95% CI, mean

# Two-sample: do 4-cyl and 8-cyl cars have different mpg?
mpg_4 <- mtcars$mpg[mtcars$cyl == 4]
mpg_8 <- mtcars$mpg[mtcars$cyl == 8]

result <- t.test(mpg_4, mpg_8, var.equal = FALSE)  # Welch's t-test
cat(sprintf("t = %.3f, df = %.1f, p = %.4f\n",
    result$statistic, result$parameter, result$p.value))
cat(sprintf("95%% CI: [%.2f, %.2f]\n",
    result$conf.int[1], result$conf.int[2]))
# p < 0.001 — strong evidence that means differ

# Paired t-test (before/after measurements)
before <- c(82, 91, 78, 88, 95, 83, 77, 90)
after  <- c(88, 95, 82, 91, 98, 87, 84, 94)
t.test(before, after, paired = TRUE)

---

Correlation Analysis

# Pearson correlation between two variables
cor(mtcars$wt, mtcars$mpg)  # -0.868 — strong negative

# Correlation matrix for multiple variables
cor_matrix <- cor(mtcars[, c("mpg", "cyl", "hp", "wt", "qsec")])
round(cor_matrix, 3)

# Correlation with significance test
cor.test(mtcars$wt, mtcars$mpg)
# Shows: r, t-statistic, p-value, 95% CI

# Visualize correlation matrix
library(ggplot2)
library(reshape2)
melted <- melt(cor_matrix)
ggplot(melted, aes(Var1, Var2, fill = value)) +
  geom_tile() +
  scale_fill_gradient2(low="#B71C1C", mid="white", high="#1565C0", midpoint=0) +
  geom_text(aes(label=round(value, 2)), size=3) +
  labs(title="Correlation Matrix", fill="r") +
  theme_minimal()

---

ANOVA and Chi-Square

# One-way ANOVA: does mpg differ by cylinder count?
model <- aov(mpg ~ factor(cyl), data = mtcars)
summary(model)
# F = 39.7, p < 2e-16 — yes, significant difference

# Post-hoc: which pairs differ? (Tukey HSD)
TukeyHSD(model)

# Chi-square test: independence between categorical variables
# Are transmission type (am) and cylinder count (cyl) independent?
table_data <- table(mtcars$cyl, mtcars$am)
chi_result <- chisq.test(table_data)
cat(sprintf("Chi-square: %.3f, df: %d, p: %.4f\n",
    chi_result$statistic, chi_result$parameter, chi_result$p.value))

---

Cohen's d (Effect Size)

cohens_d <- function(x, y) {
  pooled_sd <- sqrt(((length(x)-1)*var(x) + (length(y)-1)*var(y)) /
                    (length(x) + length(y) - 2))
  abs(mean(x) - mean(y)) / pooled_sd
}

d <- cohens_d(mpg_4, mpg_8)
cat(sprintf("Cohen's d = %.2f (%s)\n", d,
    ifelse(d < 0.2, "negligible",
    ifelse(d < 0.5, "small",
    ifelse(d < 0.8, "medium", "large")))))
0%