Point-Biserial Correlation
The engine for Binary-Continuous Synergy. This model quantifies the association between a dichotomous grouping and a continuous scale, bridging the gap between t-tests and correlation.
What is it?
Point-Biserial Correlation (r_pb) measures the linear relationship strength between one naturally binary variable (0 or 1) and one continuous outcome.
When to use it
- One Binary: Independent variable is binary (e.g. Male/Female, Employed/Unemployed).
- One Continuous: Dependent variable is continuous (e.g. salary, weight).
Core Idea
It assesses if the continuous scores shift vertically between the binary categories. The further apart the group means are, the higher the point-biserial correlation:
If the group means are identical, the correlation is exactly 0. As they separate, r_pb approaches 1.00.
Hypotheses
How it works
- Group the continuous outcomes by the binary category.
- Compute the means (Y0_mean, Y1_mean) and standard deviation of all scores.
- Multiply mean difference by standard deviation scaling factor.
- Test using t-statistic with df = N_1 + N_2 - 2.
Assumptions
Important Note
💡 t-test Equivalence: The point-biserial correlation is directly related to the Independent Samples t-test. Testing r_pb = 0 yields the identical p-value as the t-test comparing the two group means!
Quick Example
| Group (X) | Outcome (Y) |
|---|---|
| 0 (Control) | 48.2 |
| 1 (Active) | 72.5 |
Point-Biserial Correlation Laboratory
Adjust the correlation slider to shift the group separation and drive the t-statistic.
| Metric | Value |
|---|---|
| Group 0 Mean | 51.04 |
| Group 1 Mean | 56.71 |
| Point-Biserial (r_pb) | 0.4000 |
| t-statistic | 2.390 |
| p-value | 0.0178 |
Hypotheses
Pragmatic null and alternative hypotheses defined in mathematical notation.
H₀: ρpb = 0 (no correlation between dichotomous and continuous variable)
Hₐ: ρpb ≠ 0 (correlation exists between dichotomous and continuous variable)
Mathematically equivalent to Pearson r when one variable is truly dichotomous (0/1). Can also be one-tailed if directional hypothesis specified. Point-biserial r is identical to independent t-test in testing group mean differences.
Assumptions
The core mathematical criteria needed to ensure that statistical testing remains unbiased and valid.
Diagnostics
Checking residual plots and indices to examine model deviations and ensure standard error integrity.
- Confirm binary variable has exactly 2 unique values (0/1 or coded as factor)
- Shapiro-Wilk test for normality of continuous variable within each binary group
- Levene's test for homogeneity of variances
- Boxplots by group to check for outliers and variance equality
- Descriptive statistics (M, SD, n) for continuous variable in each binary group
- Q-Q plots for normality check within each group
- Visual biserial plot: jittered scatterplot showing continuous var by binary group
- Compare point-biserial r with independent t-test result (should be equivalent)
- Bootstrap 95% CI for r_pb as sensitivity check
- Compute Glass's delta or Hedges' g for additional effect size perspective
Applied Minds
Review concrete study examples, data layout guidelines, and copy executable syntax scripts.
Meditation Practice and Stress (Meditators vs Non-Meditators)
Research question: Is meditation practice (yes/no) associated with perceived stress levels? Design: Cross-sectional survey (N=150) with binary meditation variable (0=non-meditator n=75, 1=meditator n=75) and continuous Perceived Stress Scale score (0-40, higher=more stress). This tests whether meditators have different stress levels than non-meditators.
# Point-Biserial Correlation: Meditation (binary) and Stress (continuous)
# Research: Are meditators less stressed than non-meditators?
# Install/load packages
library(tidyverse)
library(psych) # For describe.by
library(car) # For Levene's test
library(effsize) # For Cohen's d
# Simulate realistic data (or load: data <- read.csv("meditation_stress.csv"))
set.seed(2025)
data <- data.frame(
meditator = rep(c(0, 1), each=75), # Binary: 0=no, 1=yes
stress_score = c(
rnorm(75, mean=26.5, sd=7.2), # Non-meditators: higher stress
rnorm(75, mean=22.1, sd=6.8) # Meditators: lower stress
)
)
# Convert to factor for clarity (optional)
data$meditator_factor <- factor(data$meditator,
levels=c(0,1),
labels=c("Non-meditator", "Meditator"))
# === STEP 1: Check Assumptions ===
# 1. Confirm binary variable has exactly 2 levels
cat("=== Binary Variable Check ===\n")
cat("Unique values:", unique(data$meditator), "\n")
table(data$meditator_factor)
# 2. Normality within each group (Shapiro-Wilk)
cat("\n=== Normality Tests(Shapiro-Wilk) ===\n")
by(data$stress_score, data$meditator_factor, shapiro.test)
# Look for p > .05 in both groups
# Q-Q plots by group
par(mfrow=c(1,2))
qqnorm(data$stress_score[data$meditator==0], main="Non-meditators Q-Q Plot")
qqline(data$stress_score[data$meditator==0])
qqnorm(data$stress_score[data$meditator==1], main="Meditators Q-Q Plot")
qqline(data$stress_score[data$meditator==1])
# 3. Homogeneity of variance (Levene's test)
cat("\n=== Levene's Test ===\n")
levene_result <- leveneTest(stress_score ~ meditator_factor, data=data)
print(levene_result)
# p > .05 indicates equal variances
# 4. Outliers (Boxplots)
ggplot(data, aes(x=meditator_factor, y=stress_score, fill=meditator_factor)) +
geom_boxplot(alpha=0.6) +
geom_jitter(width=0.1, alpha=0.3) +
labs(title="Stress Levels by Meditation Practice",
x="Group", y="Perceived Stress Score(0-40)") +
scale_fill_brewer(palette="Set2") +
theme_classic() +
theme(legend.position="none")
# Look for outliers (points >1.5 IQR from box)
# === STEP 2: Descriptive Statistics ===
cat("\n=== Descriptive Statistics ===\n")
describe.by(data$stress_score, group=data$meditator_factor)
# === STEP 3: Compute Point-Biserial Correlation ===
cat("\n=== Point-Biserial Correlation ===\n")
# Method 1: Using cor.test (treats as Pearson r)
rpb_result <- cor.test(data$meditator, data$stress_score, method="pearson")
print(rpb_result)
cat(sprintf("\nr_pb = %.3f, 95%% CI [%.3f, %.3f], p = %.4f\n",
rpb_result$estimate,
rpb_result$conf.int[1],
rpb_result$conf.int[2],
rpb_result$p.value))
# Method 2: Manual calculation (for understanding)
# r_pb = (M₁ - M₀) / SD_total * sqrt(p * q)
# where p = proportion in group 1, q = 1-p
M0 <- mean(data$stress_score[data$meditator==0])
M1 <- mean(data$stress_score[data$meditator==1])
SD_total <- sd(data$stress_score)
p <- mean(data$meditator) # Proportion in group 1
q <- 1 - p
rpb_manual <- ((M1 - M0) / SD_total) * sqrt(p * q)
cat(sprintf("\nManual r_pb calculation: %.3f\n", rpb_manual))
# === STEP 4: Relationship to Independent t-test ===
cat("\n=== Independent t-test(equivalent test) ===\n")
ttest_result <- t.test(stress_score ~ meditator_factor, data=data, var.equal=TRUE)
print(ttest_result)
# Convert t to r_pb: r_pb = sqrt(t² / (t² + df))
t_value <- ttest_result$statistic
df <- ttest_result$parameter
rpb_from_t <- sqrt(t_value^2 / (t_value^2 + df))
cat(sprintf("\nr_pb from t-test: %.3f (matches cor.test)\n", rpb_from_t))
# === STEP 5: Effect Sizes ===
cat("\n=== Effect Sizes ===\n")
# r_pb and r_pb²
cat(sprintf("Point-biserial r: %.3f\n", rpb_result$estimate))
cat(sprintf("r_pb²: %.3f (%.1f%% variance explained)\n",
rpb_result$estimate^2, 100*rpb_result$estimate^2))
# Cohen's d (standardized mean difference)
cohen_d <- cohen.d(stress_score ~ meditator_factor, data=data)
print(cohen_d)
# Interpret effect sizes
if(abs(rpb_result$estimate) < 0.1) {
r_interpretation <- "negligible"
} else if(abs(rpb_result$estimate) < 0.3) {
r_interpretation <- "small"
} else if(abs(rpb_result$estimate) < 0.5) {
r_interpretation <- "medium"
} else {
r_interpretation <- "large"
}
cat(sprintf("\nInterpretation: %s effect(Cohen, 1988)\n", r_interpretation))
# Relationship between r_pb and Cohen's d
# When groups equal size: d ≈ 2r / sqrt(1 - r²)
d_from_r <- 2 * rpb_result$estimate / sqrt(1 - rpb_result$estimate^2)
cat(sprintf("Cohen's d from r_pb: %.3f\n", d_from_r))
# === STEP 6: Visualize Results ===
# Violin plot with individual points
ggplot(data, aes(x=meditator_factor, y=stress_score, fill=meditator_factor)) +
geom_violin(alpha=0.5, trim=FALSE) +
geom_boxplot(width=0.15, alpha=0.7) +
geom_jitter(width=0.05, alpha=0.3) +
stat_summary(fun=mean, geom="point", size=3, color="red", shape=18) +
stat_summary(fun=mean, geom="text", aes(label=sprintf("M=%.1f", ..y..)),
vjust=-1, color="red", size=4) +
labs(title=sprintf("Meditation and Stress: r_pb = %.3f, p = %.3f",
rpb_result$estimate, rpb_result$p.value),
x="Meditation Practice", y="Perceived Stress Score") +
scale_fill_brewer(palette="Set2") +
theme_classic() +
theme(legend.position="none")
# === STEP 7: Bootstrap 95% CI (sensitivity check) ===
library(boot)
boot_rpb <- function(data, indices) {
d <- data[indices,]
cor(d$meditator, d$stress_score)
}
set.seed(2025)
boot_results <- boot(data, boot_rpb, R=1000)
boot_ci <- boot.ci(boot_results, type="perc")
cat("\n=== Bootstrap 95% CI ===\n")
print(boot_ci)
# === APA-Style Reporting ===
cat("\n=== APA-Style Report ===\n")
cat(sprintf(
"A point-biserial correlation was computed to assess the relationship between\nmeditation practice(yes/no) and perceived stress. Assumptions were checked:\nnormality was confirmed within each group(Shapiro-Wilk p > .05), homogeneity\nof variance was satisfied(Levene's test, p = %.3f), and no extreme outliers\nwere detected.\n\nThere was a significant negative association between meditation practice and\nstress, r_pb = %.3f, p = %.3f, 95%% CI [%.3f, %.3f]. Meditation practice\nexplained %.1f%% of the variance in stress scores(r²_pb = %.3f). Meditators\n(M = %.2f, SD = %.2f) reported significantly lower stress than non-meditators\n(M = %.2f, SD = %.2f), t(%d) = %.2f, p = %.3f, Cohen's d = %.2f. This represents\na %s effect size(Cohen, 1988), suggesting meditation is associated with\nmeaningfully lower stress levels.\n",
levene_result$`Pr(>F)`[1],
rpb_result$estimate, rpb_result$p.value,
rpb_result$conf.int[1], rpb_result$conf.int[2],
100*rpb_result$estimate^2, rpb_result$estimate^2,
M1, sd(data$stress_score[data$meditator==1]),
M0, sd(data$stress_score[data$meditator==0]),
ttest_result$parameter, ttest_result$statistic, ttest_result$p.value,
cohen_d$estimate,
r_interpretation
))r_pb = -0.32, p < .001, indicating a significant negative association between meditation practice and stress. Meditators (M=22.1, SD=6.8) reported lower stress than non-meditators (M=26.5, SD=7.2), explaining 10.2% of stress variance. This medium effect size (Cohen, 1988) suggests meditation is associated with clinically meaningful stress reduction, consistent with meta-analytic findings (Sharma & Rush, 2014).
Alternatives
Structured fallback pathways for choosing alternative tests when normality or slopes requirements fail.
- Mann-Whitney U — Use the U-statistic to derive the rank-biserial effect size.
- Bootstrap rpb — Generate robust confidence intervals for the categorical bond.
- Welch's Strike — Calculate the significance using the Welch t-test basis to protect against heteroscedasticity.
Post-hoc
Group mean comparisons and correction controls (e.g. Tukey HSD, Bonferroni) to protect against Family-Wise Error Rates.
- Compare point-biserial r with rank-biserial r (robustness check)
- Bootstrap confidence intervals
- Examine influence of outliers (with/without sensitivity)
- Compare with independent t-test (should yield same p-value)
- Check if relationship holds with logistic regression (if predicting binary from continuous)
Point-biserial correlation is a single test (2 groups). No post-hoc tests needed.
Effect Size
Understanding effect sizes (e.g., Cohen's d, Partial Eta-Squared) and clinical impact benchmarks.
Same as Pearson r: Small: .10, Medium: .30, Large: .50 (Cohen, 1988). Negative r_pb means group coded 1 has lower continuous variable values than group coded 0
Proportion of variance in continuous variable explained by group membership. Example: r_pb = .30 → r² = .09 → 9% variance explained
Standardized mean difference: Small: 0.2, Medium: 0.5, Large: 0.8. Relationship to r_pb when groups equal size: d ≈ 2r / sqrt(1 - r²)
r_pb ↔ Cohen's d: d = 2r / sqrt(1 - r²); r = d / sqrt(d² + 4) [when groups equal size]
0.2
0.5
0.8
Sample Size
Guidelines for minimum sample requirements and power analysis parameters.
At least 30 observations total (15 per group minimum) for stable correlation estimates and valid significance tests
| Effect Size | Parameters | Required n |
|---|---|---|
| Small Effect | α=.05, power=.80 | n ≈ 783 |
| Medium Effect | α=.05, power=.80 | n ≈ 84 |
| Large Effect | α=.05, power=.80 | n ≈ 28 |
Reporting
How to compile statistical results into publication prose matching APA and journal style guides.
A point-biserial correlation was computed to assess the relationship between binary variable with 2 levels specified and continuous variable. State assumption checks: 'Assumptions were met: normality within each group (Shapiro-Wilk p > .05), homogeneity of variance (Levene's test, p = .XX), and absence of extreme outliers.' Or describe violations and remedies. There was a significant/non-significant positive/negative association, r_pb = .XX, p = .XXX, 95% CI .XX, .XX. Group coded 1 (M = XX.X, SD = X.X) scored higher/lower on continuous variable than group coded 0 (M = XX.X, SD = X.X), t(df) = X.XX, p = .XXX, Cohen's d = X.XX. This represents a small/medium/large effect size (Cohen, 1988). Interpret in research context.
- r_pb correlation coefficient with p-value
- 95% confidence interval for r_pb
- r²_pb (variance explained)
- Mean and SD for continuous variable in each binary group
- Sample sizes for each group
- Independent t-test result (t, df, p) - equivalent test
- Cohen's d or Hedges' g
- Statement about assumption checks
Manuscript Lab
Copy standard summary tables and forensic reporting grids to outline analysis details.
| Comparison | r_pb | t-statistic | p-value | r² |
|---|---|---|---|---|
| Group ↔ Recovery Score | .55 | 5.42 | < .001 | .30 |
| Gender ↔ Anxiety Level | .12 | 1.05 | .298 | .01 |
The Binary Bridge. Mathematically equivalent to Pearson r, but specific to one dichotomous variable.
Variance Explained. 30% of the variation in Recovery Scores is explained by which Group the patient was in.
Command Center
Syntax libraries and function parameters for executing calculations in stats packages.
# 1. Execute Point-Biserial
cor.test(df$binary, df$continuous)
# 2. Polyserial Extension (if binary is actually ordinal)
ltm::polyserial(df$continuous, df$binary)r_pb is mathematically related to the t-test. A significant r_pb always means a significant t-test difference between the two groups.
# Convert t-statistic to r_pb
effectsize::t_to_r(t_stat, df_error)Common Mistakes
Analytical caveats and corrections to maintain modeling integrity.
References
Scholarly lineage and citation keys grounding the statistical framework.