sensuc {rms}R Documentation

Sensitivity to Unmeasured Covariables

Description

Performs an analysis of the sensitivity of a binary treatment (XX) effect to an unmeasured binary confounder (UU) for a fitted binary logistic or an unstratified non-time-dependent Cox survival model (the function works well for the former, not so well for the latter). This is done by fitting a sequence of models with separately created UU variables added to the original model. The sequence of models is formed by simultaneously varying aa and bb, where aa measures the association between UU and XX and bb measures the association between UU and YY, where YY is the outcome of interest. For Cox models, an approximate solution is used by letting YY represent some binary classification of the event/censoring time and the event indicator. For example, YY could be just be the event indicator, ignoring time of the event or censoring, or it could be 11 if a subject failed before one year and 00 otherwise. When for each combination of aa and bb the vector of binary values UU is generated, one of two methods is used to constrain the properties of UU. With either method, the overall prevalence of UU is constrained to be prev.u. With the default method (or.method="x:u y:u"), UU is sampled so that the X:UX:U odds ratio is aa and the Y:UY:U odds ratio is bb. With the second method, UU is sampled according to the model logit(U=1X,Y)=α+βY+γXlogit(U=1 | X, Y) = \alpha + \beta*Y + \gamma*X, where β=log(b)\beta=\log(b) and γ=log(a)\gamma=\log(a) and α\alpha is determined so that the prevalence of U=1U=1 is prev.u. This second method results in the adjusted odds ratio for Y:UY:U given XX being bb whereas the default method forces the unconditional (marginal) Y:UY:U odds ratio to be bb. Rosenbaum uses the default method.

There is a plot method for plotting objects created by sensuc. Values of aa are placed on the x-axis and observed marginal odds or hazards ratios for UU (unadjusted ratios) appear on the y-axis. For Cox models, the hazard ratios will not agree exactly with XX:event indicator odds ratios but they sometimes be made close through judicious choice of the event function. The default plot uses four symbols which differentiate whether for the a,ba,b combination the effect of XX adjusted for UU (and for any other covariables that were in the original model fit) is positive (usually meaning an effect ratio greater than 1) and "significant", merely positive, not positive and non significant, or not positive but significant. There is also an option to draw the numeric value of the XX effect ratio at the aa,bb combination along with its ZZ statistic underneath in smaller letters, and an option to draw the effect ratio in one of four colors depending on the significance of the ZZ statistic.

Usage

# fit <- lrm(formula=y ~ x + other.predictors, x=TRUE, y=TRUE)  #or
# fit <- cph(formula=Surv(event.time,event.indicator) ~ x + other.predictors,
#            x=TRUE, y=TRUE)

sensuc(fit,  
       or.xu=seq(1, 6, by = 0.5), or.u=or.xu, 
       prev.u=0.5, constrain.binary.sample=TRUE, 
       or.method=c("x:u y:u","u|x,y"),
       event=function(y) if(is.matrix(y))y[,ncol(y)] else 1*y)

## S3 method for class 'sensuc'
plot(x,  ylim=c((1+trunc(min(x$effect.u)-.01))/
                   ifelse(type=='numbers',2,1),
                   1+trunc(max(x$effect.u)-.01)),
     xlab='Odds Ratio for X:U',
     ylab=if(x$type=='lrm')'Odds Ratio for Y:U' else
          'Hazard Ratio for Y:U',
     digits=2, cex.effect=.75, cex.z=.6*cex.effect,
     delta=diff(par('usr')[3:4])/40, 
     type=c('symbols','numbers','colors'),
     pch=c(15,18,5,0), col=c(2,3,1,4), alpha=.05,
     impressive.effect=function(x)x > 1,...)

Arguments

fit

result of lrm or cph with x=TRUE, y=TRUE. The first variable in the right hand side of the model formula must have been the binary XX variable, and it may not interact with other predictors.

x

result of sensuc

or.xu

vector of possible odds ratios measuring the X:UX:U association.

or.u

vector of possible odds ratios measuring the Y:UY:U association. Default is or.xu.

prev.u

desired prevalence of U=1U=1. Default is 0.5, which is usually a "worst case" for sensitivity analyses.

constrain.binary.sample

By default, the binary UU values are sampled from the appropriate distributions conditional on YY and XX so that the proportions of U=1U=1 in each sample are exactly the desired probabilities, to within the closeness of n×n\timesprobability to an integer. Specify constrain.binary.sample=FALSE to sample from ordinary Bernoulli distributions, to allow proportions of U=1U=1 to reflect sampling fluctuations.

or.method

see above

event

a function classifying the response variable into a binary event for the purposes of constraining the association between UU and YY. For binary logistic models, event is left at its default value, which is the identify function, i.e, the original YY values are taken as the events (no other choice makes any sense here). For Cox models, the default event function takes the last column of the Surv object stored with the fit. For rare events (high proportion of censored observations), odds ratios approximate hazard ratios, so the default is OK. For other cases, the survival times should be considered (probably in conjunction with the event indicators), although it may not be possible to get a high enough hazard ratio between UU and YY by sampling UU by temporarily making YY binary. See the last example which is for a 2-column Surv object (first column of response variable=event time, second=event indicator). When dichotomizing survival time at a given point, it is advantageous to choose the cutpoint so that not many censored survival times preceed the cutpoint. Note that in fitting Cox models to examine sensitivity to UU, the original non-dichotomized failure times are used.

ylim

y-axis limits for plot

xlab

x-axis label

ylab

y-axis label

digits

number of digits to the right of the decimal point for drawing numbers on the plot, for type="numbers" or type="colors".

cex.effect

character size for drawing effect ratios

cex.z

character size for drawing ZZ statistics

delta

decrement in yy value used to draw ZZ values below effect ratios

type

specify "symbols" (the default), "numbers", or "colors" (see above)

pch

4 plotting characters corresponding to positive and significant effects for XX, positive and non-significant effects, not positive and not significant, not positive but significant

col

4 colors as for pch

alpha

significance level

impressive.effect

a function of the odds or hazard ratio for XX returning TRUE for a positive effect. By default, a positive effect is taken to mean a ratio exceeding one.

...

optional arguments passed to plot

Value

sensuc returns an object of class "sensuc" with the following elements: OR.xu (vector of desired X:UX:U odds ratios or aa values), OOR.xu (observed marginal X:UX:U odds ratios), OR.u (desired Y:UY:U odds ratios or bb values), effect.x (adjusted odds or hazards ratio for XX in a model adjusted for UU and all of the other predictors), effect.u (unadjusted Y:UY:U odds or hazards ratios), effect.u.adj (adjusted Y:UY:U odds or hazards ratios), ZZ (Z-statistics), prev.u (input to sensuc), cond.prev.u (matrix with one row per aa,bb combination, specifying prevalences of UU conditional on YY and XX combinations), and type ("lrm" or "cph").

Author(s)

Frank Harrell
Mark Conaway
Department of Biostatistics
Vanderbilt University School of Medicine
fh@fharrell.com, mconaway@virginia.edu

References

Rosenbaum, Paul R (1995): Observational Studies. New York: Springer-Verlag.

Rosenbaum P, Rubin D (1983): Assessing sensitivity to an unobserved binary covariate in an observational study with binary outcome. J Roy Statist Soc B 45:212–218.

Lee WC (2011): Bounding the bias of unmeasured factors with confounding and effect-modifying potentials. Stat in Med 30:1007-1017.

See Also

lrm, cph, sample

Examples

set.seed(17)
x <- sample(0:1, 500,TRUE)
y <- sample(0:1, 500,TRUE)
y[1:100] <- x[1:100]  # induce an association between x and y
x2 <- rnorm(500)


f <- lrm(y ~ x + x2, x=TRUE, y=TRUE)


#Note: in absence of U odds ratio for x is exp(2nd coefficient)


g <- sensuc(f, c(1,3))


# Note: If the generated sample of U was typical, the odds ratio for
# x dropped had U been known, where U had an odds ratio
# with x of 3 and an odds ratio with y of 3


plot(g)


# Fit a Cox model and check sensitivity to an unmeasured confounder

# require(survival)
# f <- cph(Surv(d.time,death) ~ treatment + pol(age,2)*sex, x=TRUE, y=TRUE)
# sensuc(f, event=function(y) y[,2] & y[,1] < 365.25 )
# Event = failed, with event time before 1 year
# Note: Analysis uses f$y which is a 2-column Surv object

[Package rms version 6.8-1 Index]