To help statisticians explore
wider ranges of possibilities for clinical trials, the
write_facts() function generates multiple versions of
existing FACTS files with different features. This vignette walks
through the process
FACTS files have a special XML format to define clinical trial
simulations. Most of the internal configuration settings are defined in
<property> tags inside
<parameterSet>...</parameterSet> and
<parameterSets>...</parameterSets>.
<?xml version="1.0" encoding="utf-8"?>
<facts version="6.2.5.22668" name="contin" host="host">
<parameterSets type="NucleusParameterSet">
<parameterSet name="nucleus">
<property name="type">1</property>
...
<property name="max_subjects">300</property>
<property name="cohort_size">5</property>
<property name="num_cohorts">50</property>
<property name="cohort_time">0</property>
...
</parameterSet>
</parameterSets>
...
<parameterSets type="EfficacyParameterSet">
<parameterSet name="resp2" EndpointType="1">
<property name="true_endpoint_response">
<items>
<item>0</item>
<item>10</item>
</items>
</property>
...
</parameterSet>
...
</parameterSets>
</facst>write_facts() works on the <property>
tags located above. Any <property> within a
<facts><parameterSets><parameterSet>
block can be modified programmatically. To demonstrate, we will create
two new FACTS files with modified virtual subject response scenarios and
different numbers of patients. We start with a known FACTS file we
create from the Windows GUI (or a built-in example from this
package).
library(dplyr)
library(rfacts)
library(tibble)
tmp <- file.copy(get_facts_file_example("contin.facts"), getwd())
facts_file <- "contin.facts"Next, we declare the XML fields we want to replace. We define one field to control the maximum number of subjects,
field_subjects <- tibble(
field = "my_subjects", # custom name the user can make up
type = "NucleusParameterSet", # "type" attribute of the <parameterSets> tag
set = "nucleus", # "name" attribute of the <parameterSet> tag
property = "max_subjects" # "name" attribute of the <property> tag
)and another field to modify the “resp2” virtual subject response scenario.
field_vsr <- tibble(
field = "my_vsr",
type = "EfficacyParameterSet",
set = "resp2",
property = "true_endpoint_response"
)We put the fields together in a single data frame.
fields <- bind_rows(field_subjects, field_vsr)
fields
#> # A tibble: 2 × 4
#> field type set property
#> <chr> <chr> <chr> <chr>
#> 1 my_subjects NucleusParameterSet nucleus max_subjects
#> 2 my_vsr EfficacyParameterSet resp2 true_endpoint_responseNext, we define a grid of values to iterate over when we modify these
fields. The grid should have one row per FACTS file and one column for
every value of fields$field you want to modify in the XML.
The values data frame must also contain a
facts_file column to identify the source file. You can
optionally include an output column to control the output
path of each generated FACTS file, but this is not required.
values <- tibble(
facts_file = facts_file,
my_subjects = c(1000, 2000),
my_vsr = list(c(15, 50), c(25, 75))
)
values
#> # A tibble: 2 × 3
#> facts_file my_subjects my_vsr
#> <chr> <dbl> <list>
#> 1 contin.facts 1000 <dbl [2]>
#> 2 contin.facts 2000 <dbl [2]>Above, my_subjects is a vector of max sample sizes, and
my_vsr is a list of VSR response means (one for each
treatment group). Each value of my_vsr will be inserted as
an <item> list in each output FACTS file, and the
length of each list element must equal the length of the original
<item> list.
To generate the FACTS files, simply call
write_facts().
write_facts(fields = fields, values = values)
#> [1] "_facts/38b2cfd4.facts" "_facts/00e8e729.facts"
list.files("_facts")
#> [1] "00e8e729.facts" "38b2cfd4.facts"To control the output paths, add an output column to the
values data frame.
To verify that the generated FACTS files are correct, you can open
them in a text or XML editor. Above, small.facts should
have 1000 max subjects and resp2 VSR parameters equal to
15 and 50.
<?xml version="1.0" encoding="utf-8"?>
<facts version="6.2.5.22668" name="contin" host="host">
<parameterSets type="NucleusParameterSet">
<parameterSet name="nucleus">
<property name="max_subjects">1000</property>
...
</parameterSet>
</parameterSets>
...
<parameterSets type="EfficacyParameterSet">
<parameterSet name="resp2" EndpointType="1">
<property name="true_endpoint_response">
<items>
<item>15</item>
<item>50</item>
</items>
</property>
...
</parameterSet>
...
</parameterSets>
</facst>Likewise, large.facts should have 2000 max subjects and
resp2 VSR parameters equal to 25 and
75.
<?xml version="1.0" encoding="utf-8"?>
<facts version="6.2.5.22668" name="contin" host="host">
<parameterSets type="NucleusParameterSet">
<parameterSet name="nucleus">
<property name="max_subjects">2000</property>
...
</parameterSet>
</parameterSets>
...
<parameterSets type="EfficacyParameterSet">
<parameterSet name="resp2" EndpointType="1">
<property name="true_endpoint_response">
<items>
<item>25</item>
<item>75</item>
</items>
</property>
...
</parameterSet>
...
</parameterSets>
</facst>Other ways to check your work include the following.
run_facts() and check that the
output is consistent with the input settings you specified.read_facts() to inspect the settings that should be
modified.read_facts(facts_file = facts_file, fields = fields)
#> # A tibble: 1 × 3
#> facts_file my_subjects my_vsr
#> <chr> <chr> <list>
#> 1 contin.facts 300 <chr [2]>
read_facts(facts_file = "small.facts", fields = fields)
#> # A tibble: 1 × 3
#> facts_file my_subjects my_vsr
#> <chr> <chr> <list>
#> 1 small.facts 1000 <chr [2]>
read_facts(facts_file = "large.facts", fields = fields)
#> # A tibble: 1 × 3
#> facts_file my_subjects my_vsr
#> <chr> <chr> <list>
#> 1 large.facts 2000 <chr [2]>