R Basics for Psychological Research

Descriptives, Correlation, and Multiple Regression

Author

Dr. Anisha Singh

Overview

In this session we will work through a complete data analysis workflow using a simulated dataset from psychological research. The dataset contains the following variables for 150 students:

Variable Description Scale
student_id Participant identifier ID only
study_hours Average daily study hours 0-12 hours
sleep_hours Average nightly sleep 3-11 hours
anxiety_score Trait anxiety (adapted from STAI) 20-80 (higher = more anxiety)
exam_score Final exam performance 0-100

Research question: Do study hours, sleep hours, and anxiety predict exam performance?


Step 1: Load Libraries

Use install.packages("psych") once if you have not installed it yet. Then load it each session:

library(psych)   # for the describe() function

A library (package) is a collection of pre-written functions that extend base R. Load with library() at the top of every script.


Step 2: Import the Dataset

df <- read.csv("psych_study_data.csv")
head(df)     # first 6 rows
  student_id study_hours sleep_hours anxiety_score exam_score
1          1         5.7         6.8            49       66.4
2          2         5.7         5.2            53       54.3
3          3         5.6         7.1            52       69.1
4          4         7.3         7.1            43       62.5
5          5         6.5         8.6            50       66.4
6          6         7.1         5.3            47       69.0
dim(df)      # rows x columns
[1] 150   5
names(df)    # variable names
[1] "student_id"    "study_hours"   "sleep_hours"   "anxiety_score"
[5] "exam_score"   

Always inspect your data after importing to confirm row counts and variable names look correct.


Step 3: Descriptive Statistics

3a. Mean and Standard Deviation (base R)

mean(df$exam_score)
[1] 63.14267
mean(df$study_hours)
[1] 6.115333
mean(df$sleep_hours)
[1] 6.925333
mean(df$anxiety_score)
[1] 50.58667
sd(df$exam_score)
[1] 12.09133
sd(df$study_hours)
[1] 1.904595
sd(df$sleep_hours)
[1] 1.252926
sd(df$anxiety_score)
[1] 10.21197

A larger SD indicates more variability around the mean; a smaller SD means scores cluster tightly.

3b. Rich Descriptives with psych::describe()

# Drop column 1 (student_id) before describing
describe(df[, -1])
              vars   n  mean    sd median trimmed   mad  min  max range  skew
study_hours      1 150  6.12  1.90   6.00    6.13  1.93  0.8 10.6   9.8 -0.08
sleep_hours      2 150  6.93  1.25   7.00    6.91  1.11  3.9  9.8   5.9  0.04
anxiety_score    3 150 50.59 10.21  51.00   50.62  8.90 27.0 80.0  53.0  0.07
exam_score       4 150 63.14 12.09  62.35   63.29 11.93 33.8 97.0  63.2 -0.02
              kurtosis   se
study_hours      -0.20 0.16
sleep_hours      -0.17 0.10
anxiety_score     0.24 0.83
exam_score       -0.25 0.99

Key columns: n (sample size), mean, sd, median, min, max, skew (0 = symmetric), kurtosis (0 = normal), se (standard error of the mean).


Step 4: Correlation with cor.test()

cor.test() returns Pearson r and tests whether it differs significantly from zero.

Study Hours and Exam Score

cor.test(df$study_hours, df$exam_score)

    Pearson's product-moment correlation

data:  df$study_hours and df$exam_score
t = 10.014, df = 148, p-value < 2.2e-16
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 0.5291560 0.7222259
sample estimates:
     cor 
0.635523 

Anxiety Score and Exam Score

cor.test(df$anxiety_score, df$exam_score)

    Pearson's product-moment correlation

data:  df$anxiety_score and df$exam_score
t = -3.9774, df = 148, p-value = 0.0001087
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 -0.4486713 -0.1583807
sample estimates:
       cor 
-0.3107545 

Sleep Hours and Exam Score

cor.test(df$sleep_hours, df$exam_score)

    Pearson's product-moment correlation

data:  df$sleep_hours and df$exam_score
t = 3.2379, df = 148, p-value = 0.001486
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 0.1011083 0.4009372
sample estimates:
      cor 
0.2572022 

Reading the output: - cor: Pearson r (range -1 to +1) - t: test statistic - df: degrees of freedom (n - 2) - p-value: probability of this result if the true r = 0 - 95 percent confidence interval: plausible range for the true r

Effect size convention (Cohen, 1988): |r| < .10 = negligible; .10-.29 = small; .30-.49 = moderate; >= .50 = large.


Step 5: Multiple Regression

Multiple regression estimates how several predictors jointly explain an outcome and the unique contribution of each predictor controlling for the others.

model <- lm(exam_score ~ study_hours + sleep_hours + anxiety_score, data = df)
summary(model)

Call:
lm(formula = exam_score ~ study_hours + sleep_hours + anxiety_score, 
    data = df)

Residuals:
    Min      1Q  Median      3Q     Max 
-17.801  -5.827  -0.101   5.199  17.417 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)   36.66864    5.35935   6.842 2.00e-10 ***
study_hours    4.19120    0.33653  12.454  < 2e-16 ***
sleep_hours    2.82049    0.51175   5.511 1.57e-07 ***
anxiety_score -0.36945    0.06265  -5.897 2.47e-08 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 7.805 on 146 degrees of freedom
Multiple R-squared:  0.5917,    Adjusted R-squared:  0.5833 
F-statistic: 70.53 on 3 and 146 DF,  p-value: < 2.2e-16

Reading the output:

Coefficients table: - Estimate: regression slope (B) - Std. Error: precision of the estimate - t value: test statistic (H0: B = 0) - Pr(>|t|): p-value; *** <= .001, ** <= .01, * <= .05

Model fit: - Multiple R-squared: proportion of variance in exam score explained by all predictors combined - Adjusted R-squared: R-squared penalized for number of predictors (preferred for comparisons) - F-statistic: tests whether the overall model is significant

Interpreting a slope: for every one-unit increase in a predictor, exam score changes by B points holding all other predictors constant.


Step 6: Scatterplot (Bonus)

plot(df$study_hours, df$exam_score,
     xlab = "Study Hours (per day)",
     ylab = "Exam Score",
     main = "Study Hours and Exam Performance",
     pch = 19, col = "steelblue", cex = 0.7)
abline(lm(exam_score ~ study_hours, data = df),
       col = "firebrick", lwd = 2)


Function Quick Reference

library(psych)
df <- read.csv("psych_study_data.csv")
head(df)
dim(df)
names(df)
mean(df$variable)
sd(df$variable)
describe(df[, -1])
cor.test(df$x, df$y)
model <- lm(y ~ x1 + x2 + x3, data = df)
summary(model)

References

Cohen, J. (1988). Statistical power analysis for the behavioral sciences (2nd ed.). Lawrence Erlbaum Associates.

Revelle, W. (2023). psych: Procedures for psychological, psychometric, and personality research. R package version 2.3.6.