After many mistakes, ChatGPT eventually provided me with a solution to the problem of extracting the tau2 and tau statistics from the list (adjusted_confint) generated by confint acting on the list selmodel produced. See below. I'm love to hear of any simpler approach.
?
I had to stop confint providing output for the fixed effects:
# Function to eventually get Tau2 using confint on results from selmodel
perform_confint <- function(xxx) {
adjusted_confint <- confint(xxx, level=90, fixed=FALSE, tau2=TRUE, type="PL")
return(adjusted_confint)
}
?
# Extract a list of tau^2 and tau estimates and confidence limits
adjseltau <- sapply(adjusted_confint, function(x) x[1])
# Convert the list to a matrix
adjseltau_matrix <- do.call(rbind, adjseltau)
# Split the matrix into two parts: one for tau^2 and one for tau
adjtau2matrix <- adjseltau_matrix[row.names(adjseltau_matrix) == "tau^2", , drop = FALSE]
adjtaumatrix <- adjseltau_matrix[row.names(adjseltau_matrix) == "tau", , drop = FALSE]
# Convert adjtau2matrix to a data frame to allow addition of a coverage variable
adjtau2df <- as.data.frame(adjtau2matrix)
adjtau2df$Coverage <- 0
adjtau2df$Coverage[adjtau2df$ci.lb<TrueHeteroSD^2 & TrueHeteroSD^2<adjtau2df$ci.ub] <- 100
# Calculate the means for estimate, ci.lb, ci.ub and coverage for tau2
colMeans(adjtau2df, na.rm = TRUE, na.rm = TRUE)
Here's the result (I have yet to get the decimal places right), for a true tau2 of 0.25 (TrueHeteroSD=0.5):
estimate ci.lb ci.ub Coverage
0.4570235 0.1342391 1.1630262 76.8800000
(The tau is much less biased, not shown here, but the coverage is of course the same and not looking good.)
Interestingly, there were no missing values:
#Number of simulations with non-missing values:
colSums(!is.na(adjtau2df))
Here's the result:
estimate ci.lb ci.ub Coverage
2500 2500 2500 2500
It's interesting, because the adjusted SE for tau2 provided by selmodel was missing in about 100 simulations, so evidently confint does not use the SE of tau2 to generate the adjusted confidence limits for tau2. I'm probably misunderstanding something here.
Will
From: Will Hopkins <willthekiwi at gmail.com>
Sent: Monday, March 11, 2024 11:41 AM
To: 'R Special Interest Group for Meta-Analysis' <r-sig-meta-analysis at r-project.org>
Subject: RE: [R-meta] Extracting values from a list of confint() objects
Tobias, that dataset appears to be for a single meta, not a set of many (simulated) metas for checking bias and coverage of the fixed effects and tau2. Nevertheless I tried the last few steps on my list of confint objects (adjusted_confint).
#get an overview of the list, so that you can see what you need to extract
str(adjusted_confint)
List of 2500
$ :List of 2
..$ fixed : num [1:2, 1:3] 1.5 1.74 1.05 1.1 1.95 ...
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr [1:2] "intrcpt" "mods"
.. .. ..$ : chr [1:3] "estimate" "ci.lb" "ci.ub"
..$ digits: Named num [1:9] 4 4 4 4 4 4 4 4 4
.. ..- attr(*, "names")= chr [1:9] "est" "se" "test" "pval" ...
..- attr(*, "class")= chr "confint.rma"
$ :List of 2
..$ fixed : num [1:2, 1:3] 1.665 1.191 1.148 0.563 2.183 ...
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr [1:2] "intrcpt" "mods"
.. .. ..$ : chr [1:3] "estimate" "ci.lb" "ci.ub"
..$ digits: Named num [1:9] 4 4 4 4 4 4 4 4 4
.. ..- attr(*, "names")= chr [1:9] "est" "se" "test" "pval" ...
..- attr(*, "class")= chr "confint.rma"
etc., etc.
I find this hard to understand, but it looks like the stats for tau2 may not be in there.
The next step didn't work:
data frame with 0 columns and 0 rows
Nor did the alternative version you suggested:
adjsel <- as.data.frame(adjusted_confint$random)
adjsel
data frame with 0 columns and 0 rows
However, my adjust_conflim was generated with this line of code within a function:
adjusted_confint <- confint(xxx, level=90, fixed=TRUE, random=TRUE, type="PL")
So I made it:
adjusted_confint <- confint(xxx, level=90, fixed=FALSE, tau2=TRUE, type="PL")
Now str(adjusted_confint) gave this:
$ :List of 5
..$ random : num [1:2, 1:3] 0.909 0.954 0.303 0.55 2.108 ...
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr [1:2] "tau^2" "tau"
.. .. ..$ : chr [1:3] "estimate" "ci.lb" "ci.ub"
..$ digits : Named num [1:9] 4 4 4 4 4 4 4 4 4
.. ..- attr(*, "names")= chr [1:9] "est" "se" "test" "pval" ...
..$ ci.null: logi FALSE
..$ lb.sign: chr ""
..$ ub.sign: chr ""
..- attr(*, "class")= chr "confint.rma"
$ :List of 5
etc., etc.
So we're nearly there. I don?t know how to translate the above information into code that will extract the values of tau^2, tau, and their confidence limits. Your previous suggestions, adjsel <- as.data.frame(adjusted_confint[["random"]]) and adjsel <- as.data.frame(adjusted_confint$random), still gave:
data frame with 0 columns and 0 rows
And my attempts to use sapply() still don't work. I hope you can suggest something else, or point out any silly mistake I might be making.
Thanks
Will
From: R-sig-meta-analysis <r-sig-meta-analysis-bounces at r-project.org <mailto:r-sig-meta-analysis-bounces at r-project.org> > On Behalf Of Tobias Saueressig via R-sig-meta-analysis
Sent: Monday, March 11, 2024 12:42 AM
To: r-sig-meta-analysis at r-project.org <mailto:r-sig-meta-analysis at r-project.org>
Cc: Tobias Saueressig <t.saueressig at gmx.de <mailto:t.saueressig at gmx.de> >
Subject: Re: [R-meta] Extracting values from a list of confint() objects
Dear Will,
you can do the following to get the values:
install.packages("metafor")
library(metafor)
dat <- dat.baskerville2012
dat
# fit random-effects model
res <- rma(smd, se^2, data=dat, method="ML", digits=3)
res
sel <- selmodel(res, type="beta")
sel
#calculate confidence interval for tau2
a <- confint(sel,tau2=TRUE)
#get an overview of the list, so that you can see what you need to extract
str(a)
#extract tau2 and tau from list
c <- as.data.frame(a[["random"]])
c
#you can also use $ to get access
d <- as.data.frame(a$random)
d
#now you can export the data e.g. to excel
install.packages("openxlsx")
library(openxlsx)
# Export data to an Excel file
write.xlsx(d, "tau2_data.xlsx", rowNames = FALSE)
Best Regards,
Tobias
Gesendet: Sonntag, 10. M?rz 2024 um 05:58 Uhr
Von: "Will Hopkins via R-sig-meta-analysis" < <mailto:r-sig-meta-analysis at r-project.org> r-sig-meta-analysis at r-project.org>
An: "'R Special Interest Group for Meta-Analysis'" < <mailto:r-sig-meta-analysis at r-project.org> r-sig-meta-analysis at r-project.org>
Cc: "Will Hopkins" < <mailto:willthekiwi at gmail.com> willthekiwi at gmail.com>
Betreff: [R-meta] Extracting values from a list of confint() objects
With the help of ChatGPT, I have managed to extract values from a list of
rma() objects and values from a list of selmodel() objects derived from the
list of rma() objects. However, I cannot extract values from a list of
confint() objects derived from the selmodel() objects. I hope I am using the
right jargon here. If not, please be gentle, as I am still on the steep part
of the learning curve.
For example, this code (mysteriously) extracts tau2 from meta_results, which
is a list of rma objects:
tau2 <- sapply(meta_results, function(x) x$tau2).
And this code (equally mysteriously) extracts the SE of tau2 from
adjusted_meta, which is a list of selmodel objects derived by applying
selmodel() to meta_results:
seltau2se <- sapply(adjusted_meta, function(x) x$se.tau2).
But I have a list I have called adjusted_confint, which is a list of confint
objects derived by applying confint to the list adjusted_meta. I don't know
how to use sapply on this list to extract the confidence limits for tau2
that are contained within this list. I have "copied blindly" the syntax of
the other sapply statements without success. Basically I don't know what to
put for the x$..., and everything I have tried fails. ChatGPT was not
helpful here. I hope a real maven can help here. Thanks.
Will
_______________________________________________
R-sig-meta-analysis mailing list @ <mailto:R-sig-meta-analysis at r-project.org> R-sig-meta-analysis at r-project.org
To manage your subscription to this mailing list, go to:
<https://stat.ethz.ch/mailman/listinfo/r-sig-meta-analysis> https://stat.ethz.ch/mailman/listinfo/r-sig-meta-analysis