[R package] Log Response Ratio and Effect Size Calculation (feat. lrr)

When conducting a meta-analysis, results from multiple studies must be synthesized despite differences in measurement scales, experimental designs, and reported units. To enable meaningful comparisons across studies, effect sizes are commonly used. One of the most widely applied effect size metrics in ecological and agricultural research is the Log Response Ratio (LRR).
The Log Response Ratio is calculated as:
LRR = ln(Xt / Xc)
where Xt represents the mean response of the treatment group and Xc represents the mean response of the control group.
This metric expresses the proportional change caused by a treatment on a logarithmic scale, making it dimensionless and comparable across studies.
The LRR offers an intuitive interpretation: positive values indicate an increase in the response variable due to treatment, negative values indicate a decrease, and a value of zero indicates no treatment effect.
Because it standardizes treatment effects relative to controls, LRR is particularly useful for assessing how response variables such as crop yield, biomass, or nutrient uptake respond to experimental treatments across diverse experimental contexts.
In addition to reporting the Log Response Ratio (LRR), it is essential to present its 95% confidence interval (CI). While the LRR provides a point estimate of the magnitude and direction of a treatment effect, the confidence interval quantifies the uncertainty and precision associated with that estimate. The 95% confidence interval represents the range within which the true effect size is expected to lie with 95% confidence, given the sampling variability of the data. In meta-analysis, where effect sizes are synthesized across studies with differing sample sizes and variances, this information is critical for proper interpretation. Moreover, the width of the confidence interval reflects the precision of the estimated effect size. Narrow confidence intervals indicate high precision, often resulting from large sample sizes or low variability, whereas wide intervals indicate greater uncertainty. This distinction is particularly important in meta-analysis, where studies with more precise estimates are typically given greater weight in the overall analysis through inverse-variance weighting.
To easily calculate LRR with CI, I developed a new R function named, lrr().

1. Install lrr() package
Before installing, please download Rtools (https://cran.r-project.org/bin/windows/Rtools)
if(!require(remotes)) install.packages("remotes")
if (!requireNamespace("lrr", quietly= TRUE)) {
remotes::install_github("agronomy4future/lrr", force= TRUE)
}
library(remotes)
library(lrr)
2. Data example
df= data.frame(Cultivar= rep(c("CV1", "CV2", "CV3", "CV4", "CV5", "CV6", "CV7", "CV8"), each = 4L), Block= rep(c("I", "II", "III", "IV"), 8), N0= c(608.9, 464.7, 199.3, 930, 623.7, 43.1, 200.3, 207.7, 1243.7, 776.7, 1424.5, 1556.4, 352.2, 1316.7, 377.7, 980.8, 660.9, 1535.5, 1009.2, 1490.8, 692.6, 1273.9, 1010.7, 1105.8, 695, 869, 396, 1147, 883.9, 786.6, 416.2, 1512.6),N1= c(697.6, 601.9, 1063.4, 440.6, 313, 109.9, 119.9, 281.3, 3463.1, 1364.8, 1991.9, 1264, 1837.9, 1382.5, 1160.5, 248.9, 1679.7, 1704.4, 1631.7, 1065.9, 2466.4, 1324.5, 3790.1, NA, 1735, 872.3, 2314, NA, 2001.4, 1700.4, 2521.4, NA))
print(head (df, 5))
Cultivar Block N0 N1
1 CV1 I 608.9 697.6
2 CV1 II 464.7 601.9
3 CV1 III 199.3 1063.4
4 CV1 IV 930.0 440.6
5 CV2 I 623.7 313.0
.
.
.
3. Run code
output= lrr(data= df, trt= N0, ctrl= N1, group = c("Cultivar"))
print(output)
Cultivar n_T n_C n_LRR LRR LRR_L LRR_U Cohen_d Hedges_g
1 CV1 4 4 4 -0.330514832 -1.924442 1.2634125 -0.5269730 -0.4582374
2 CV2 4 4 4 -0.009187594 -1.209322 1.1909472 0.3279905 0.2852091
3 CV3 4 4 4 -0.428739063 -1.243705 0.3862267 -1.0188530 -0.8859592
4 CV4 4 4 4 -0.363033297 -2.487070 1.7610031 -0.6920945 -0.6018213
5 CV5 4 4 4 -0.295524032 -1.154888 0.5638399 -0.9486484 -0.8249117
6 CV6 3 3 3 -0.876921152 -2.680809 0.9269668 -1.7118456 -1.3694765
7 CV7 3 3 3 -0.894653273 -3.083024 1.2937177 -1.8273893 -1.4619115
8 CV8 3 3 3 -1.129853628 -2.575724 0.3160167 -4.0361639 -3.2289311
If the Block is included, the CI is not calculated because there are no replicates, but this LRR values can be used for geom_jitter.
output1= lrr(data= df, trt= N0, ctrl= N1, group = c("Cultivar", "Block"))
print(output1)
Cultivar Block n_T n_C n_LRR LRR LRR_L LRR_U Cohen_d Hedges_g
1 CV1 I 1 1 1 -0.135991822 NA NA NA NA
2 CV2 I 1 1 1 0.689466293 NA NA NA NA
3 CV3 I 1 1 1 -1.024073334 NA NA NA NA
4 CV4 I 1 1 1 -1.652179698 NA NA NA NA
5 CV5 I 1 1 1 -0.932767943 NA NA NA NA
6 CV6 I 1 1 1 -1.270062245 NA NA NA NA
7 CV7 I 1 1 1 -0.914850847 NA NA NA NA
8 CV8 I 1 1 1 -0.817258281 NA NA NA NA
9 CV1 II 1 1 1 -0.258699282 NA NA NA NA
10 CV2 II 1 1 1 -0.936047864 NA NA NA NA
11 CV3 II 1 1 1 -0.563709001 NA NA NA NA
12 CV4 II 1 1 1 -0.048764848 NA NA NA NA
13 CV5 II 1 1 1 -0.104357082 NA NA NA NA
14 CV6 II 1 1 1 -0.038951969 NA NA NA NA
15 CV7 II 1 1 1 -0.003790276 NA NA NA NA
16 CV8 II 1 1 1 -0.770898936 NA NA NA NA
17 CV1 III 1 1 1 -1.674415374 NA NA NA NA
18 CV2 III 1 1 1 0.513158181 NA NA NA NA
19 CV3 III 1 1 1 -0.335268082 NA NA NA NA
20 CV4 III 1 1 1 -1.122505996 NA NA NA NA
21 CV5 III 1 1 1 -0.480464478 NA NA NA NA
22 CV6 III 1 1 1 -1.321749244 NA NA NA NA
23 CV7 III 1 1 1 -1.765318696 NA NA NA NA
24 CV8 III 1 1 1 -1.801403668 NA NA NA NA
25 CV1 IV 1 1 1 0.747047152 NA NA NA NA
26 CV2 IV 1 1 1 -0.303326985 NA NA NA NA
27 CV3 IV 1 1 1 0.208094166 NA NA NA NA
28 CV4 IV 1 1 1 1.371317356 NA NA NA NA
29 CV5 IV 1 1 1 0.335493376 NA NA NA NA
4. Visualization
ggplot() +
geom_jitter(data= output1, aes(x= Cultivar, y= LRR, fill= Cultivar, shape= Cultivar),
width=0.2, alpha=0.5, size=2, color="grey75") +
geom_point(data=output, aes(x=Cultivar, y=LRR, fill=Cultivar, shape=Cultivar),
color= "black", size= 3) +
geom_errorbar(data=output, aes(x=Cultivar, ymin= LRR_L, ymax= LRR_U),
width=0.2, linewidth=0.5, color="black") +
geom_hline(yintercept=0, linetype="dashed", color= "red") +
scale_fill_manual(values = c("cadetblue", "darkred", "orange", "darkblue", "grey35",
"purple", "darkolivegreen", "coral3")) +
scale_shape_manual(values = rep(22, 8)) +
scale_y_continuous(breaks = seq(-4, 4, 1), limits = c(-4, 4)) +
coord_flip () +
labs(x="Cultivar", y="Effect size (Log Response Ratio)") +
theme_classic(base_size= 18, base_family = "serif") +
theme(legend.position="none",
legend.title=element_blank(),
legend.key=element_rect(color="white", fill=alpha(0.5)),
legend.text=element_text(family="serif", face="plain",
size=15, color="black"),
legend.background= element_rect(fill=alpha(0.5)),
strip.background=element_rect(color="white",
linewidth=0.5,linetype="solid"),
panel.border= element_rect(color="black", fill=NA, linewidth=0.5),
axis.line= element_line(linewidth= 0.5, colour= "black"))

Code summary: https://github.com/agronomy4future/r_code/blob/main/Log__Response_Ratio_and_Effect_Size_Calculation.ipynb

We aim to develop open-source code for agronomy ([email protected])
© 2022 – 2025 https://agronomy4future.com – All Rights Reserved.
Last Updated: 12/15/2025