The Friedman Test is a non-parametric alternative to the Repeated Measures ANOVA. It is used to determine whether or not there is a statistically significant difference between the means of three or more groups in which the same subjects show up in each group.
This tutorial explains how to perform the Friedman Test in R.
Example: The Friedman Test in R
To perform the Friedman Test in R, we can use the friedman.test() function, which uses the following syntax:
friedman.test(y, groups, blocks)
where:
- y: a vector of response values.
- groups: a vector of values indicating the “group” an observation belongs in.
- blocks: a vector of values indicating the “blocking” variable.
This function produces a Chi-Square test statistic and a corresponding p-value. If the p-value is less than a certain significance level (common choices are 0.10, 0.05, and 0.01), then there is sufficient evidence that the means between each of the groups is not equal.
To illustrate how to use this function, we will create a dataset that shows the reaction time of five patients on four different drugs. Since each patient is measured on each of the four drugs, we will use the Friedman Test to determine if the mean reaction time differs between drugs.
First, we’ll create the dataset:
#create data data <- data.frame(person = rep(1:5, each=4), drug = rep(c(1, 2, 3, 4), times=5), score = c(30, 28, 16, 34, 14, 18, 10, 22, 24, 20, 18, 30, 38, 34, 20, 44, 26, 28, 14, 30)) #view data data person drug score 1 1 1 30 2 1 2 28 3 1 3 16 4 1 4 34 5 2 1 14 6 2 2 18 7 2 3 10 8 2 4 22 9 3 1 24 10 3 2 20 11 3 3 18 12 3 4 30 13 4 1 38 14 4 2 34 15 4 3 20 16 4 4 44 17 5 1 26 18 5 2 28 19 5 3 14 20 5 4 30
Then we’ll perform the Friedman Test using score as the response variable, drug as the grouping variable, and person as the blocking variable:
#perform Friedman Test
friedman.test(y=data$score, groups=data$drug, blocks=data$person)
Friedman rank sum test
data: data$score, data$drug and data$person
Friedman chi-squared = 13.56, df = 3, p-value = 0.00357
The Chi-Squared test statistic is 13.56 and the corresponding p-value is 0.00357. Because this p-value is less than 0.05, we can reject the null hypothesis that the mean response time is the same for all four drugs. We have sufficient evidence to conclude that the type of drug used lead to statistically significant differences in response time.
Although a Friedman Test tells us if there are differences in mean response time across the drugs, it doesn’t tell us specifically which drugs have different mean response times. To figure that out, we need to conduct post-hoc tests.
For a Friedman Test, the appropriate post-hoc test is the pairwise Wilcoxon rank sum test with a bonferroni correction, which can be implemented using the following syntax:
pairwise.wilcox.test(data$score, data$drug, p.adj = “bonf”)
where:
- x: response vector
- g: grouping vector
- p.adj: method for adjusting p-values; options include holm, hochberg, hommel, bonferroni, BH, BY, fdr, and none
Here is the syntax we will use for our example:
#perform post-hoc tests
pairwise.wilcox.test(data$score, data$drug, p.adj = "bonf")
Pairwise comparisons using Wilcoxon rank sum test
data: data$score and data$drug
1 2 3
2 1.000 - -
3 0.449 0.210 -
4 1.000 1.000 0.072
P value adjustment method: bonferroni
This produces a matrix that shows the p-value for each pairwise Wilcoxon rank sum test. We can see that the only drug groups that have a statistically significant difference at 0.10 are groups 3 and 4 (p = 0.072).
Hello, could you please tell me which R packages need to be installed to run this test? Thankyou
Hello,
Can you please tell me what packages are required to run the Friedmans and Wilcox Test in R? Thankyou
Hello,
Nice post.
Don’t you have to add ‘paired = TRUE’ in the pairwise Wilcox test ?
Something does not make sense here. We have a stat. sign. result with the alpha=0.05 level as is usually done. But then at the 0.05 level there isn’t a single stat. sign. pair? I do not get this. These two tests contradict each other. You may not assume one significance level and then raise it to 0.10 level.
step wise procedure. easy to understand.
Scenario: have two independent groups (A & B); the dependent variable is measured three times (T1, T2 & T3) for each participant on a continuous scale but not meeting the assumption of normality.
my question is: what is the syntax to identify whether or not there is a statistically significant difference between groups.
Thanks for the clear scenario! The **Friedman Test** is **used for *repeated measures* within the *same group***—not for comparing *independent groups*. But don’t worry, I’ll walk you through the correct approach for your scenario and clarify where Friedman fits in:
—
### 🔍 Your Scenario:
– You have **two independent groups** (A and B)
– A **dependent variable** measured at **three time points** (T1, T2, T3)
– Data is **non-normal**, and you’re dealing with **repeated measures** → likely need a **non-parametric test**
—
## ✅ Correct Approach:
Since the Friedman test is **within-subjects** only (e.g., for Group A alone across T1, T2, T3), you’d **run Friedman tests separately for each group** to see if scores change across time.
If you’re trying to compare **Group A vs Group B** over time (i.e., **group × time interaction**), that’s more complex and requires a non-parametric alternative to **repeated-measures ANOVA with between-subjects factor**, which Friedman alone doesn’t cover. You may need a **non-parametric mixed-model** approach like **nparLD** or **aligned ranks transformation ANOVA**.
—
## 🔧 Friedman Test in R (for one group):
Here’s the step-by-step process assuming you’re testing changes over time within **Group A** or **Group B** separately.
—
### 🛠 Step-by-Step Procedure (Example for Group A):
1. **Prepare your data** in long format:
“`r
# Example data
id <- rep(1:10, each = 3) # 10 participants time <- rep(c("T1", "T2", "T3"), times = 10) score <- c(5, 6, 7, 6, 7, 8, 4, 5, 6, 3, 4, 5, 5, 5, 6, 6, 7, 8, 4, 4, 5, 6, 6, 7, 5, 5, 6, 6, 6, 7) group <- rep("A", 30) df <- data.frame(id, time, score, group) ``` 2. **Subset Group A**: ```r group_a <- subset(df, group == "A") ``` 3. **Run Friedman Test**: ```r friedman.test(score ~ time | id, data = group_a) ``` - `score ~ time` → dependent variable across time - `| id` → repeated measures for each subject --- ### 🧪 What if you want to compare groups? If your goal is to test whether **Group A vs Group B change differently over time**, try the `nparLD` package: ```r install.packages("nparLD") library(nparLD) # Your data must be in long format nparLD_result <- f1.ld.f1(y = df$score, time = df$time, group = df$group, subject = df$id) summary(nparLD_result) ``` --- ### 📝 Interpretation: - If **p < 0.05**, then there are significant differences across time or between groups. - `nparLD` will show: - Main effect of **group** - Main effect of **time** - **Group × Time interaction** ---