anoint, for ANalysis Of INTeractions, is a package written in the R language, which provides a suite of tools for investigating heterogeneity of treatment effect in a clinical trial.
Stephanie Kovalchik
Research Fellow, National Cancer Institute
anoint, for ANalysis Of INTeractions, is a package written in the R language, which provides a suite of tools for investigating heterogeneity of treatment effect in a clinical trial.
anoint PackageOpen-source software
Written in the R language
Provides methods for assessing heterogeneity of treatment effect, including:
RR is a statistical programming environment
It is maintained by the R Development Core Team
It can be run on Windows, Linux, and Mac OS platiforms
It can be downloaded from http://cran.r-project.org/
R as a Calculator(1:3)^2
## [1] 1 4 9
(1:3) * (4:6)
## [1] 4 10 18
R to Store & Manipulate Dataobject <- data.frame(x = 1:6, y = rep(1, 6))
object
## x y
## 1 1 1
## 2 2 1
## 3 3 1
## 4 4 1
## 5 5 1
## 6 6 1
object[1, ]
## x y
## 1 1 1
R to Import Datathedata <- read.csv("filename")
R to Perform Statistical Analyses of All Kindsquantile(object$x)
## 0% 25% 50% 75% 100%
## 1.00 2.25 3.50 4.75 6.00
R to Perform Statistical Analyses of All Kindsqqnorm(rnorm(100))
R by Writing Functionsis.missing <- function(x) NA %in% x
is.missing(object$x)
## [1] FALSE
sapply(object, is.missing)
## x y
## FALSE FALSE
R by Installing Contributed PackagesThe rapid development of R is owing to the contributions of a growing community of programmers (mostly academics), who are willing to share their work with others.
After passing some quality checks, these packages are posted to the Comprehensive R Archive Network (CRAN), which can be accessed directly from the R environment.
install.packages("package-name")
Install R (http://cran.r-project.org/)
Install anoint package from CRAN (Version 1.3)
Rinstall.packages("anoint")
anointAll sessions with the anoint begin by loading the package.
library(anoint)
anoint's dependent packages will need to be installed An index of all of the functions of anoint can be obtained
by using the help function.
Click the link for any function to bring up documentation describing its use.
help(package = "anoint")
You can also use `?' as a shortcut to a function's documentation.
`?`(anoint)
anoint package| Function | Description |
anoint |
Creates an analysis of interactions object |
obo |
Extract one-by-one subgroup analyses from anoint object |
uim |
Extract unrestricted multiple interaction regression from anoint object |
pim.subsets |
Perform all subsets proportional interactions modeling |
pim.fit |
Fit a specific proportional interactions model |
forest.subsets |
Forest plot of all subsets procedure |
We will demonstrate the major tools of the anoint package with a bootstrap SOLVD-T dataset.
If this is located in the current directory, it can be loaded into the R session with the function load.
setwd("~/master/project/anoint/tutorial") # On My System
load("solvd.RData")
str(solvd) # Show Structure
## 'data.frame': 2569 obs. of 10 variables:
## $ enal : int 0 0 0 0 0 0 0 0 0 0 ...
## $ deathdays : num 723 835 1547 1051 1449 ...
## $ death : num 0 0 0 0 0 1 1 0 0 0 ...
## $ vaso : int 0 0 1 0 1 0 0 1 0 1 ...
## $ ischemia : int 1 1 1 1 1 0 1 1 0 1 ...
## $ sodium : int 144 140 142 140 135 143 139 136 142 136 ...
## $ lvef : int 35 28 24 26 24 15 17 35 22 16 ...
## $ nyha : int 2 2 3 3 3 2 2 2 3 2 ...
## $ sodium.cat: Ord.factor w/ 3 levels "<140"<"140-141"<..: 3 2 3 2 1 3 1 1 3 1 ...
## $ lvef.cat : Ord.factor w/ 3 levels "<23"<"23-29"<..: 3 2 2 2 2 1 1 3 1 1 ...
enal: Indicator of enalapril treatment group (1=enalapril, 0=placebo)deathdays: Days to death or last date of follow-up if still alivedeath: Indicator of deathvaso: Indicator of prior vasodilator use (1=use, 0=no use)ischemia: Indicator of ischemic cause of congestive heart failuresodium: Sodium level (mmol/liter)lvef: Left ventricular ejection fraction (as percent)nyha: NYHA prognostic class (1 - 4, 1=best and 4=worst)anoint Objectanoint(formula, data, family, ...)
| Argument | Description |
formula |
Model formula |
data |
Data frame containing formula variables |
family |
coxph or any of glm families, i.e. gaussian, binomial, etc. |
anoint Formula SpecificationThe formula used to create an anoint object requires
a response (appropriate for the model)
covariates
a treatment variable
anoint Formula SpecificationSuppose:
response = y
covariates = a, b, c
treatment variable = trt
formula = y ~ (a + b + c) * trt
anointfit <- anoint(
formula = Surv(deathdays, death) ~ (vaso + ischemia + lvef + sodium + nyha) * enal,
data = solvd,
family = "coxph")
anointclass(fit)
## [1] "anoint"
## attr(,"package")
## [1] "anoint"
anoint Object| Method | Description |
print |
Shows formula |
summary |
Shows formula, covariates |
obo |
Returns results of one-by-one subgroup analyses |
uim |
Returns unrestricted interaction model |
print Method for anointfit
## Surv(deathdays, death) ~ (vaso + ischemia + lvef + sodium + nyha) *
## enal
obo Method for anointReturns a list with the following named components:
fit: list of model objects; length equal to the number of covariates
LRT: vector of likelihood ratio test (LRT) statistics for interaction
pvalue: vector of unadjusted p-values for LRTs
obo Methodsubgroups <- obo(fit)
names(subgroups)
## [1] "fit" "LRT" "pvalue"
obo Methodsubgroups$LRT
## vaso ischemia lvef sodium nyha
## 2.4068 1.4669 4.1930 0.2081 3.7393
subgroups$pvalue
## vaso ischemia lvef sodium nyha
## 0.12081 0.22584 0.04059 0.64828 0.05315
obo methodsubgroups$fit[[1]] ## Cox model for vasodilator
## Call:
## coxph(formula = f, data = anoint@data)
##
##
## coef exp(coef) se(coef) z p
## vaso -0.00504 0.995 0.0902 -0.0559 0.960
## enal -0.17119 0.843 0.0968 -1.7678 0.077
## vaso:enal 0.20119 1.223 0.1297 1.5516 0.120
##
## Likelihood ratio test=5.45 on 3 df, p=0.142 n= 2569, number of events= 966
obo methodbetas <- sapply(subgroups$fit, function(x) x$coef[1]) ## Covariate effects in placebo group
betas
## Surv(deathdays, death) ~ vaso * enal.vaso
## -0.005044
## Surv(deathdays, death) ~ ischemia * enal.ischemia
## -0.057539
## Surv(deathdays, death) ~ lvef * enal.lvef
## -0.047876
## Surv(deathdays, death) ~ sodium * enal.sodium
## -0.040647
## Surv(deathdays, death) ~ nyha * enal.nyha
## 0.549418
obo Methodinteractions <- sapply(subgroups$fit, function(x) x$coef[3]) # Interaction
interactions
## Surv(deathdays, death) ~ vaso * enal.vaso:enal
## 0.201191
## Surv(deathdays, death) ~ ischemia * enal.ischemia:enal
## 0.174479
## Surv(deathdays, death) ~ lvef * enal.lvef:enal
## 0.019561
## Surv(deathdays, death) ~ sodium * enal.sodium:enal
## 0.009408
## Surv(deathdays, death) ~ nyha * enal.nyha:enal
## -0.189664
obo Methodinteractions/betas + 1 # implied proportional effects
## Surv(deathdays, death) ~ vaso * enal.vaso:enal
## -38.8847
## Surv(deathdays, death) ~ ischemia * enal.ischemia:enal
## -2.0324
## Surv(deathdays, death) ~ lvef * enal.lvef:enal
## 0.5914
## Surv(deathdays, death) ~ sodium * enal.sodium:enal
## 0.7685
## Surv(deathdays, death) ~ nyha * enal.nyha:enal
## 0.6548
uim Method for anointReturns a list with the same named components as obo:
fit: fitted model object
LRT: value of global likelihood ratio test (LRT) for any interaction
pvalue: value of corresponding LRT
uim Methodunrestricted <- uim(fit) # Cox multiple interaction model
names(unrestricted)
## [1] "fit" "LRT" "pvalue"
uim Methodunrestricted$LRT
## [1] 7.693
unrestricted$pvalue
## [1] 0.174
uim Methodunrestricted$fit
## Call:
## coxph(formula = object@formula@formula, data = object@data)
##
##
## coef exp(coef) se(coef) z p
## vaso -3.15e-02 0.9690 0.09271 -0.339303 7.3e-01
## ischemia 1.16e-05 1.0000 0.10174 0.000114 1.0e+00
## lvef -3.82e-02 0.9626 0.00677 -5.636172 1.7e-08
## sodium -4.07e-02 0.9601 0.01434 -2.837351 4.5e-03
## nyha 4.64e-01 1.5897 0.06782 6.835390 8.2e-12
## enal -2.45e+00 0.0863 2.89633 -0.845774 4.0e-01
## vaso:enal 1.73e-01 1.1889 0.13286 1.302541 1.9e-01
## ischemia:enal 1.44e-01 1.1547 0.14823 0.970554 3.3e-01
## lvef:enal 9.85e-03 1.0099 0.00974 1.010600 3.1e-01
## sodium:enal 1.65e-02 1.0167 0.02062 0.801963 4.2e-01
## nyha:enal -1.44e-01 0.8655 0.09909 -1.457243 1.5e-01
##
## Likelihood ratio test=154 on 11 df, p=0 n= 2569, number of events= 966
uim Methodbetas <- unrestricted$fit$coef[1:5] # covariate placebo effects
betas
## vaso ischemia lvef sodium nyha
## -3.146e-02 1.157e-05 -3.815e-02 -4.069e-02 4.636e-01
uim Methodinteractions <- unrestricted$fit$coef[7:11] # interaction effects
interactions
## vaso:enal ischemia:enal lvef:enal sodium:enal nyha:enal
## 0.173049 0.143865 0.009846 0.016537 -0.144392
uim Methodinteractions/betas + 1 # implied proportional effect
## vaso:enal ischemia:enal lvef:enal sodium:enal nyha:enal
## -4.5014 12438.0717 0.7419 0.5936 0.6885
We see from the subgroup and unrestricted interaction effects that there is some suggestion of proportionality among the SOLVD-T candidate effect modifiers.
To investigate this formally, we can use the function pim.subsets
pim.subsets FunctionThe syntax of the pim.subsets function is very similar to the function anoint.
pim.subsets(formula, data, family, trt, ...)
pim.subsets FunctionHowever, rather than specifying the treatment variable as part of formula, the name of the treatment variable is indicated in the argument trt.
pim.subsets(formula, data, family, trt, ...)
pim.subsets Functionfit.subsets <- pim.subsets(
formula = Surv(deathdays, death) ~ vaso + ischemia + lvef + sodium + nyha,
trt = "enal", data = solvd, family = "coxph")
## subset interaction num LRT lower upper pvalue reject
## 9 01101 0.7434 3 8.90024 0.5952 0.9016 0.0028513 TRUE
## 24 11101 0.7343 4 9.42195 0.5937 0.8863 0.0021440 TRUE
## 2 00101 0.7331 2 9.65005 0.6021 0.8891 0.0018935 TRUE
## 16 10101 0.7245 3 10.15835 0.5874 0.8781 0.0014365 TRUE
## 11 01111 0.7261 4 10.78335 0.5929 0.8809 0.0010242 TRUE
## 26 11111 0.7163 5 11.50786 0.5897 0.8653 0.0006930 TRUE
## 4 00111 0.7150 3 11.65697 0.5799 0.8680 0.0006396 TRUE
## 18 10111 0.7061 4 12.29694 0.5736 0.8647 0.0004537 TRUE
## 13 10010 1.0887 2 0.01920 0.2238 5.9074 0.8897986 FALSE
## 21 11010 1.1774 3 0.06677 0.2932 5.1624 0.7961048 FALSE
## 6 01010 0.8401 2 0.08374 0.2047 3.3398 0.7722924 FALSE
## 23 11100 0.7154 3 1.79286 0.3812 1.1946 0.1805778 FALSE
## 25 11110 0.7049 4 2.35769 0.4067 1.1278 0.1246666 FALSE
## 15 10100 0.6615 2 2.67703 0.3518 1.0393 0.1018056 FALSE
## 8 01100 0.6609 2 2.68945 0.3408 1.0461 0.1010148 FALSE
## 19 11000 -8.2577 2 3.13799 -25.3649 -0.3323 0.0764882 FALSE
## 10 01110 0.6636 3 3.23664 0.3783 1.0168 0.0720084 FALSE
## 17 10110 0.6545 3 3.35297 0.3678 0.9975 0.0670837 FALSE
## 20 11001 0.6633 3 3.37300 0.3876 1.0071 0.0662730 FALSE
## 12 10001 0.6630 2 3.41665 0.3870 1.0331 0.0645417 FALSE
## 5 01001 0.6599 2 3.54650 0.3933 1.0205 0.0596713 FALSE
## 7 01011 0.6540 3 4.62729 0.4251 0.9492 0.0314672 FALSE
## 22 11011 0.6476 4 4.73537 0.4124 0.9786 0.0295486 FALSE
## 3 00110 0.6019 2 4.76715 0.3432 0.9735 0.0290078 FALSE
## 1 00011 0.6524 2 4.77758 0.4271 0.9901 0.0288327 FALSE
## 14 10011 0.6451 3 4.87995 0.4230 0.9415 0.0271704 FALSE
pim.subsets Returned ObjectA list with the named components:
subset: indicators of included covariatesinteraction: proportionality parameter estimatesLRT: LRTs for proportionality num: number of included covariateslower: lower endpoints of 95% CI for proportionality parameterupper: upper endpoints of 95% CI for proportionality parameterpvalue: p-values of corresponding LRTcovariates: covariate namesreject: vector of logical values indicating rejection of LRT at multiplicity corrected criterion (set with fwer argument)pim.subsets Functionfit.subsets$covariates
## [1] "vaso" "ischemia" "lvef" "sodium" "nyha"
pim.subsets Functioncbind(fit.subsets$subset, fit.subsets$LRT, fit.subsets$reject)
## [,1] [,2] [,3]
## [1,] "01101" "8.90023811334097" "TRUE"
## [2,] "11101" "9.42194817028956" "TRUE"
## [3,] "00101" "9.65005022459761" "TRUE"
## [4,] "10101" "10.1583522349928" "TRUE"
## [5,] "01111" "10.7833529645664" "TRUE"
## [6,] "11111" "11.5078553943072" "TRUE"
## [7,] "00111" "11.6569696787207" "TRUE"
## [8,] "10111" "12.2969384312842" "TRUE"
## [9,] "10010" "0.0191986181248966" "FALSE"
## [10,] "11010" "0.0667661675164961" "FALSE"
## [11,] "01010" "0.0837394419787868" "FALSE"
## [12,] "11100" "1.79286210618331" "FALSE"
## [13,] "11110" "2.35769090031863" "FALSE"
## [14,] "10100" "2.67702689475455" "FALSE"
## [15,] "01100" "2.68944818922313" "FALSE"
## [16,] "11000" "3.13798679990886" "FALSE"
## [17,] "01110" "3.23663577543446" "FALSE"
## [18,] "10110" "3.35297358414815" "FALSE"
## [19,] "11001" "3.37299889754784" "FALSE"
## [20,] "10001" "3.41665296927792" "FALSE"
## [21,] "01001" "3.54649768064868" "FALSE"
## [22,] "01011" "4.62728953837953" "FALSE"
## [23,] "11011" "4.73536618393853" "FALSE"
## [24,] "00110" "4.76714889609609" "FALSE"
## [25,] "00011" "4.77757528714653" "FALSE"
## [26,] "10011" "4.87995034896806" "FALSE"
forest.subsets Plotting MethodThe results of the all subsets procedure can be graphically displayed with a forest plot using the function forest.subsets.
The syntax is:
forest.subsets(object, index, labels, ...)
forest.subsets Plotting Methodforest.subsets(object, index, labels, ...)
| Argument | Description |
object |
Result of pim.subsets or anoint.subgroups |
index |
Vector specifying the PIM subsets to include |
... |
Additional arguments for plot rendering |
forest.subsets Plotting Methodforest.subsets(fit.subsets, xlimits = c(0.5, 1.25)) # With limits for x-axis
anoint.subgroups FunctionBonferroni-corrected subgroup analyses can be obtained with anoint.subgroups, which takes the same arguments as pim.subsets.
anoint.subgroups(formula, data, family, trt, ...)
anoint.subgroupsfit.subgroups <- anoint.subgroups(
formula = Surv(deathdays, death) ~ vaso + ischemia + lvef + sodium + nyha,
trt = "enal", data = solvd, family = "coxph")
## subset interaction LRT lower upper pvalue covariates
## lvef 00100 0.019561 4.1930 0.0008367 0.038285 0.04059 lvef
## nyha 00001 -0.189664 3.7393 -0.3817445 0.002416 0.05315 nyha
## vaso 10000 0.201191 2.4068 -0.0529541 0.455337 0.12081 vaso
## ischemia 01000 0.174479 1.4669 -0.1080974 0.457055 0.22584 ischemia
## sodium 00010 0.009408 0.2081 -0.0310088 0.049825 0.64828 sodium
## reject
## lvef FALSE
## nyha FALSE
## vaso FALSE
## ischemia FALSE
## sodium FALSE
anoint.subgroupscbind(fit.subgroups$cov, fit.subgroups$LRT, fit.subgroups$reject)
## [,1] [,2] [,3]
## [1,] 2 4.1930 0
## [2,] 3 3.7393 0
## [3,] 5 2.4068 0
## [4,] 1 1.4669 0
## [5,] 4 0.2081 0
forest.subsets(fit.subgroups, subgroup = TRUE)
pim.fitIf we wanted to consider a single proportional interactions model, we can do it with the pim.fit function.
object <- pim.fit(
formula = Surv(deathdays, death) ~ vaso + lvef + sodium + nyha,
trt = "enal", data = solvd, family = "coxph")
pim.fit Returned ObjectA list with the named components:
interaction: proportional effect LRT: LRT statisticlower: lower endpoint of 95% CI for proportionality parameterupper: upper endpoint of 95% CI for proportionality parameterpvalue: p-value of LRTmodel0: covariate model object in placebo groupmodel1: covariate model object in treatment grouppim.fit Returned Objectobject$interaction
## [1] 0.7061
object$LRT
## [1] 12.3
object$pvalue
## [1] 0.0004537
pim.fit Returned Objectobject$model1
## Call:
## coxph(formula = formula, data = treatment)
##
##
## coef exp(coef) se(coef) z p
## vaso 0.1607 1.174 0.09393 1.71 8.7e-02
## lvef -0.0268 0.974 0.00691 -3.88 1.0e-04
## sodium -0.0240 0.976 0.01481 -1.62 1.0e-01
## nyha 0.3263 1.386 0.07260 4.49 7.0e-06
##
## Likelihood ratio test=46 on 4 df, p=2.51e-09 n= 1285, number of events= 467
R Core Team (2013). R: A language and environment for statistical computing. R Foundation for Statistical Computing, Vienna, Austria. http://www.R-project.org/
Varadhan R, Kovalchik S (2013). anoint: Analysis of interactions. R package Version 1.3. http://CRAN.R-project.org/package=anoint
Kovalchik S, Weiss CO, Varadhan R (2013). Assessing heterogeneity of treatment effect in a clinical trial with the proportional interactions model. Statistics in Medicine, In press.