packageVersion("vtree")
## [1] '4.0.0'
library(vtree)
vtree is a great way to make CONSORT-style diagrams. Not only does vtree produce a CONSORT-style figure, it calculates the numbers in the figure. This ensures accuracy and reproducibility.
Note that vtree cannot match the exact format of the CONSORT diagram, so the final version may need to transferred to the CONSORT format.
Let’s define the following variables
rand |
Logical: Was this patient randomized? |
exc1 |
Logical: Reason not randomized (#1). |
exc2 |
Logical: Reason not randomized (#2). |
oth1 |
Logical: Other reason not randomized. |
group |
Character: “A” or “B” |
recv |
Logical: Received allocated intervention? |
not1 |
Logical: Reason allocated intervention not received (#1) |
not2 |
Logical: Reason allocated intervention not received (#2) |
fu |
Logical: Was this patient followed up? |
lost |
Logical: If not followed up, was it because lost to follow up? |
disc |
Logical: If not followed up, was it because discontinued intervention? |
exca |
Logical: Excluded from analysis? |
e1 |
Logical: Reason excluded from analysis (#1). |
e2 |
Logical: Reason excluded from analysis (#2). |
Now let’s build a data frame with these variables:
df <- build.data.frame(
c( "rand","exc1","exc2","oth1", "group","recv","not1","not2","fu", "lost","disc","exca","e1","e2"),
list(T, F, F, F, "A", T, F, F, T, F, F, F, NA, NA, 100),
list(T, F, F, F, "B", T, F, F, T, F, F, F, NA, NA, 100),
list(T, F, F, F, "A", T, F, F, T, F, F, T, T, F, 14),
list(T, F, F, F, "B", T, F, F, T, F, F, T, F, T, 27),
list(T, F, F, F, "A", T, F, F, T, F, F, T, F, T, 3),
list(T, F, F, F, "B", T, F, F, T, F, F, T, T, F, 8),
list(T, F, F, F, "A", T, F, F, T, T, F, F, NA, NA, 10),
list(T, F, F, F, "B", T, F, F, T, T, F, F, NA, NA, 20),
list(T, F, F, F, "A", T, F, F, F, T, F, F, NA, NA, 10),
list(T, F, F, F, "B", T, F, F, F, T, F, F, NA, NA, 20),
list(T, F, F, F, "A", T, F, F, F, F, T, F, NA, NA, 3),
list(T, F, F, F, "B", T, F, F, F, F, T, F, NA, NA, 2),
list(T, F, F, F, "A", F, T, F, NA, NA, NA, NA, NA, NA, 80),
list(T, F, F, F, "B", F, T, F, NA, NA, NA, NA, NA, NA, 70),
list(T, F, F, F, "A", F, F, T, NA, NA, NA, NA, NA, NA, 80),
list(T, F, F, F, "B", F, F, T, NA, NA, NA, NA, NA, NA, 70),
list(F, T, F, F, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 188),
list(F, F, T, F, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 213))
vtree(df,"rand group recv fu exca",horiz=FALSE,
title="Assessed for eligibility",
labelnode=list(
rand=c("Randomized"=TRUE,"Excluded"=FALSE),
recv=c("Received\nallocated intervention"=TRUE,"Did not receive\nallocated intervention"=FALSE),
fu=c("Followed up"=TRUE,"Not followed up"=FALSE),
exca=c("Excluded from analysis"=TRUE,"Analyzed"=FALSE)),
follow=list(rand=TRUE,recv=TRUE,fu=TRUE,exca=FALSE),
summary=c(
"exc1 \nExclusion reason 1: %sum%%var=rand%%node=FALSE%",
"exc2 \nExclusion reason 2: %sum%%var=rand%%node=FALSE%",
"not1 \nReason 1: %sum%%var=recv%%node=FALSE%",
"not2 \nReason 2: %sum%%var=recv%%node=FALSE%",
"lost \nLost to follow-up: %sum%%var=fu%%node=FALSE%",
"disc \nDiscontinued intervention: %sum%%var=fu%%node=FALSE%",
"e1 \nReason 1: %sum%%var=exca%%node=TRUE%",
"e2 \nReason 2: %sum%%var=exca%%node=TRUE%"),
fillcolor="white",splitwidth=Inf,showvarnames=FALSE,showpct=FALSE,imagewidth="10in")
The CONSORT diagram is a vertical tree, so we specify horiz=FALSE. The diagram starts with a node showing all patients assessed for eligibility. Specifying title="Assessed for eligibility" labels this node accordingly. The variables that define the tree are, in sequence, rand (was the patient randomized?), group (what group was the patient randomized to?), fu (was the patient followed up?), and exca (was the patient excluded from analysis?).
Node labels are specified using the labelnode parameter.
labelnode=list(
rand=c("Randomized"=TRUE,"Excluded"=FALSE),
recv=c("Received\nallocated intervention"=TRUE,"Did not receive\nallocated intervention"=FALSE),
fu=c("Followed up"=TRUE,"Not followed up"=FALSE),
exca=c("Excluded from analysis"=TRUE,"Analyzed"=FALSE))
The CONSORT diagram tracks patients from their assessment for eligibility, all the way through to their inclusion in the analysis. Other paths are pruned. For example, patients who are not randomized are not followed further. The pruning is specified using the follow parameter:
follow=list(rand=TRUE,recv=TRUE,fu=TRUE,exca=FALSE)
The summary parameter is used to show reasons for exclusion, etc.:
summary=c(
"exc1 \nExclusion reason 1: %sum%%var=rand%%node=FALSE%",
"exc2 \nExclusion reason 2: %sum%%var=rand%%node=FALSE%",
"not1 \nReason 1: %sum%%var=recv%%node=FALSE%",
"not2 \nReason 2: %sum%%var=recv%%node=FALSE%",
"lost \nLost to follow-up: %sum%%var=fu%%node=FALSE%",
"disc \nDiscontinued intervention: %sum%%var=fu%%node=FALSE%",
"e1 \nReason 1: %sum%%var=exca%%node=TRUE%",
"e2 \nReason 2: %sum%%var=exca%%node=TRUE%")
The %sum% code indicates that the total number of TRUE values should be tallied. The %var% and %node% codes are used to indicate which nodes the summaries should appear in.
A few other settings are used to fine-tune the display:
fillcolor="white",splitwidth=Inf,showvarnames=FALSE,showpct=FALSE,imagewidth="10in")
Specifying fillcolor="white" is used to remove the default vtree colors; splitwidth=Inf turns off line-splitting; showvarnames=FALSE suppresses variable names; showpct=FALSE suppresses percentages (which are not part of the standard CONSORT diagram); and imagewidth=10in specifies the size of the image.