---
title: "Converting t-Values to Partial Correlations: Ballesteros et al. (2013)"
author: "Danilo Assis Pereira, Ph.D."
date: "2025-01-28"
output: html_document
---
Gizem wrote: “We have 1 study having correlation data between GSH and Total symptom and functioning, but the study did not indicate their r values, which we are using r values to do meta-analysis. They gave t and F values with p value. I am wondering if you can convert these F and t values into r values to be used into our meta-analysis.”
Below we use the data reported in the Ballesteros et al. (2013) paper, specifically the t‐values for GSH and GSSG each predicting UPSA‐2 (a measure of everyday functioning) in the same sample. Note that using two effect sizes from a single paper is not a typical “meta‐analysis” in the standard sense (since a meta‐analysis usually combines results from multiple distinct samples). However, the following example demonstrates how to:
# Uncomment to install if needed:
# install.packages("metafor")
library(metafor)
Loading required package: Matrix
Loading required package: metadat
Loading required package: numDeriv
Loading the 'metafor' package (version 4.6-0). For an
introduction to the package please type: help(metafor)
# Convert (t_value, df_resid) to partial correlation
convert_t_to_partial_r <- function(t_value, df_resid) {
r_mag <- sqrt(t_value^2 / (t_value^2 + df_resid))
r_signed <- sign(t_value) * r_mag
return(r_signed)
}
# Convert correlation (r) to Fisher’s z
r_to_z <- function(r) {
0.5 * log((1 + r)/(1 - r))
}
# Approximate standard error of Fisher’s z for correlation
# (Strictly for zero-order correlations, used as an approximation for partial r.)
z_se <- function(n) {
1 / sqrt(n - 3)
}
From the article (Ballesteros et al., 2013), we know:
| Measure | t-value | df_resid | n_total |
|---|---|---|---|
| GSH vs. UPSA-2 | +2.08 | 49 | 52 |
| GSSG vs. UPSA-2 | -2.22 | 49 | 52 |
df_ballesteros <- data.frame(
measure = c("GSH", "GSSG"),
t_value = c( 2.08, -2.22),
df_resid = c(49, 49),
n_total = c(52, 52)
)
df_ballesteros
measure t_value df_resid n_total
1 GSH 2.08 49 52
2 GSSG -2.22 49 52
# 1) Partial r
df_ballesteros$partial_r <- mapply(
convert_t_to_partial_r,
df_ballesteros$t_value,
df_ballesteros$df_resid
)
# 2) Convert partial r to Fisher’s z
df_ballesteros$z <- sapply(df_ballesteros$partial_r, r_to_z)
# 3) Approximate SE for z
df_ballesteros$z_se <- sapply(df_ballesteros$n_total, z_se)
df_ballesteros
measure t_value df_resid n_total partial_r z z_se
1 GSH 2.08 49 52 0.2848342 0.2929353 0.1428571
2 GSSG -2.22 49 52 -0.3023042 -0.3120536 0.1428571
Interpretation: - partial_r: the
partial correlations.
- z: Fisher’s z.
- z_se: approximate standard error of z.
We will illustrate the metafor approach:
res <- rma(yi = df_ballesteros$z,
sei = df_ballesteros$z_se,
method = "REML")
summary(res)
Random-Effects Model (k = 2; tau^2 estimator: REML)
logLik deviance AIC BIC AICc
-0.5698 1.1396 5.1396 1.1396 17.1396
tau^2 (estimated amount of total heterogeneity): 0.1626 (SE = 0.2588)
tau (square root of estimated tau^2 value): 0.4032
I^2 (total heterogeneity / total variability): 88.85%
H^2 (total variability / sampling variability): 8.97
Test for Heterogeneity:
Q(df = 1) = 8.9673, p-val = 0.0027
Model Results:
estimate se zval pval ci.lb ci.ub
-0.0096 0.3025 -0.0316 0.9748 -0.6024 0.5833
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
predict(res, transf = transf.ztor)
pred ci.lb ci.ub pi.lb pi.ub
-0.0096 -0.5388 0.5251 -0.7606 0.7524
This yields: - pred: the mean partial correlation.
- ci.lb, ci.ub: the 95% CI in the correlation
metric.
forest(
x = df_ballesteros$z,
sei = df_ballesteros$z_se,
slab = df_ballesteros$measure,
transf = transf.ztor,
xlab = "Partial correlation (r)",
main = "Forest Plot of Partial r (Ballesteros et al. 2013)"
)
References
- Ballesteros, A., et al. (2013). No Evidence of Exogenous Origin
for the Abnormal Glutathione Redox State in Schizophrenia.
Schizophrenia Research, 146, 184–189.
- Viechtbauer, W. (2010). Conducting meta-analyses in R with the
metafor package. Journal of Statistical
Software, 36(3), 1–48.
Below is a step-by-step explanation of how to convert the overall model F(2,26)=0.30 into an \(r\) value (i.e., the multiple correlation \(R\) of the full two‐predictor model). However, this approach does not provide a unique correlation (partial or zero‐order) for GSH alone, because the paper only gives us the overall F for both GSH and GSSG together. If you specifically want the partial correlation between GSH and total symptoms (controlling for GSSG) or the zero‐order correlation for GSH alone, the paper would have needed to report an individual t (or Pearson \(r\)) for GSH vs. total symptoms. Only the overall F for the 2‐predictor model is given.
For a multiple regression with \(p\) predictors and \(\mathrm{df}_{\text{resid}}\) residual degrees of freedom, the relationship between F (the overall model test), \(R^2\) (the multiple coefficient of determination), and sample size is:
\[ F = \frac{(R^2 / p)}{\bigl[(1 - R^2) / (n - p - 1)\bigr]} \quad\Longrightarrow\quad R^2 = \frac{p \cdot F}{\,p \cdot F \;+\;\mathrm{df}_{\text{resid}}\,}. \]
Here:
Thus:
\[ R^2 = \frac{2 \times 0.30}{(2 \times 0.30) + 26} = \frac{0.60}{26.60} \approx 0.0226 \]
Hence the overall multiple correlation \(R\) is:
\[ R = \sqrt{0.0226} \approx 0.15 \]
This indicates the entire 2‐predictor model (GSH + GSSG) has \(R \approx 0.15\) with BPRS total severity—consistent with the non-significant p=0.74.
Often in meta‐analysis we prefer the Fisher’s z form of \(R\):
\[ z = \frac{1}{2} \ln\!\Bigl(\frac{1+R}{1-R}\Bigr) \]
With \(R = 0.15\):
\[ z = 0.5 \,\times\, \ln\bigl(1.15/0.85\bigr) \approx 0.5 \,\times\, 0.302 = 0.151 \]
Thus, the overall model correlation in Fisher’s z is ~0.15.
Bottom Line:
- We can convert F(2,26)=0.30 to \(R\approx
0.15\).
- That lumps both predictors into the model’s overall correlation.
Below is optional R code implementing the overall \(R^2\) formula, converting it to \(R\) and then to Fisher’s z.
#############################
## A. Fill in the known values
#############################
p <- 2 # number of predictors
f_value <- 0.30
df_resid <- 26
#############################
## B. Compute R^2 from F
#############################
r_sq <- (p * f_value) / ((p * f_value) + df_resid)
cat("Overall R^2 =", r_sq, "\n")
Overall R^2 = 0.02255639
# Overall R:
R <- sqrt(r_sq)
cat("Overall R =", R, "\n")
Overall R = 0.1501879
#############################
## C. Convert R to Fisher z
#############################
z <- 0.5 * log((1 + R)/(1 - R))
z
[1] 0.1513326
When you run this, you get:
- R^2 = 0.0226
- R = 0.15
- z = 0.151
Below we discuss why Gamze sees a small discrepancy between her Stata result (r = –0.175, p = 0.104) and an R result (r = –0.166, p = 0.0655). Essentially, Stata’s default random‐effects meta‐analysis uses the DerSimonian–Laird (DL) method to estimate between‐study variance, whereas metafor in R defaults to REML. Different estimation methods for \(\tau^2\) produce slightly different pooled estimates and p‐values.
We can replicate Gamze’s Stata result by setting
method = "DL" in metafor. That yields
r ≈ –0.175, p ≈ 0.104. If we stick with the default
(method = "REML"), we get r ≈ –0.166, p ≈ 0.066.
Both are legitimate; they differ only in how \(\tau^2\) is computed. Choose
one and report it consistently.
Gamze’s Stata result: - Pooled correlation = –0.175
(p = 0.104).
- This uses DerSimonian–Laird (DL), Stata’s default for random‐effects
meta‐analysis.
R’s metafor result (default): - Pooled correlation =
–0.166 (p = 0.066).
- Uses REML (Restricted Maximum Likelihood).
We illustrate how to replicate both results in R:
Imagine five studies reporting GSH–symptom correlations:
# Example data frame with 5 studies
df <- data.frame(
author = c("Matsuzawa et al. 2008",
"Reyes-Madrigal et al. 2019",
"Iwata et al. 2021",
"Lesh et al. 2021",
"Ravanfar et al. 2022"),
r = c(-0.41, 0.42, -0.08, -0.293, -0.286),
n = c(20, 10, 67, 33, 12)
)
df
author r n
1 Matsuzawa et al. 2008 -0.410 20
2 Reyes-Madrigal et al. 2019 0.420 10
3 Iwata et al. 2021 -0.080 67
4 Lesh et al. 2021 -0.293 33
5 Ravanfar et al. 2022 -0.286 12
df$z <- 0.5 * log((1 + df$r) / (1 - df$r))
df$var_z <- 1 / (df$n - 3)
df
author r n z var_z
1 Matsuzawa et al. 2008 -0.410 20 -0.43561122 0.05882353
2 Reyes-Madrigal et al. 2019 0.420 10 0.44769202 0.14285714
3 Iwata et al. 2021 -0.080 67 -0.08017133 0.01562500
4 Lesh et al. 2021 -0.293 33 -0.30184486 0.03333333
5 Ravanfar et al. 2022 -0.286 12 -0.29420447 0.11111111
library(metafor)
res_dl <- rma(yi = df$z,
vi = df$var_z,
data = df,
method = "DL") # DerSimonian-Laird
summary(res_dl)
Random-Effects Model (k = 5; tau^2 estimator: DL)
logLik deviance AIC BIC AICc
-0.0860 5.5191 4.1721 3.3910 10.1721
tau^2 (estimated amount of total heterogeneity): 0.0124 (SE = 0.0427)
tau (square root of estimated tau^2 value): 0.1113
I^2 (total heterogeneity / total variability): 20.71%
H^2 (total variability / sampling variability): 1.26
Test for Heterogeneity:
Q(df = 4) = 5.0451, p-val = 0.2827
Model Results:
estimate se zval pval ci.lb ci.ub
-0.1750 0.1077 -1.6246 0.1042 -0.3862 0.0361
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Back‐transform to r:
pred_dl <- predict(res_dl, transf=transf.ztor)
cat("DerSimonian-Laird (DL) overall correlation:\n")
DerSimonian-Laird (DL) overall correlation:
print(pred_dl)
pred ci.lb ci.ub pi.lb pi.ub
-0.1733 -0.3681 0.0361 -0.4452 0.1279
res_reml <- rma(yi = df$z,
vi = df$var_z,
data = df,
method = "REML")
summary(res_reml)
Random-Effects Model (k = 5; tau^2 estimator: REML)
logLik deviance AIC BIC AICc
-0.5464 1.0928 5.0928 3.8654 17.0928
tau^2 (estimated amount of total heterogeneity): 0.0013 (SE = 0.0292)
tau (square root of estimated tau^2 value): 0.0359
I^2 (total heterogeneity / total variability): 2.64%
H^2 (total variability / sampling variability): 1.03
Test for Heterogeneity:
Q(df = 4) = 5.0451, p-val = 0.2827
Model Results:
estimate se zval pval ci.lb ci.ub
-0.1678 0.0911 -1.8419 0.0655 -0.3464 0.0108 .
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Back‐transform to r:
pred_reml <- predict(res_reml, transf=transf.ztor)
cat("REML overall correlation:\n")
REML overall correlation:
print(pred_reml)
pred ci.lb ci.ub pi.lb pi.ub
-0.1662 -0.3331 0.0108 -0.3449 0.0241
forest(res_dl,
slab = df$author,
transf = transf.ztor,
xlab = "Correlation (r)",
mlab = "Pooled Effect (DL)",
main = "Random-Effects (DerSimonian-Laird)")
Across these three sections: