Incorporate the third contrast of a three-level categorical predictor into the odds ratio summary plot of a logistic regression model
In any regression model, by default, a 3-level categorical predictor generates only 2 contrasts. For example, if race was a predictor in the model and had the levels Black, Caucasian, and Other, and Caucasian was the reference level, only the contrasts of Caucasian:Black and Caucasian:Other would be calculated. It would be useful to be able to incorporate the third contrast Black:Other into the desired output.
In this specific example, the desired output is an odds ratio (OR) plot that is generated by the
Design
package's
plot.summary.Design()
function when based on a logistic regression model (defined using the
Design
pacage's
lrm()
function).
For this example, let's use our old standby -- the
samplefile.txt
data file.
Let's first load the necessary packages, read in our data file, and make some changes to our data frame -- add some variable labels, level labels, and units.
library(Hmisc)
library(Design)
x<-read.table("samplefile.txt", header=TRUE)
x<-upData(x,
labels=c(age="Age", race="Race", sex="Sex",
weight="Weight", visits="No. of Visits",
tx="Treatment"),
levels=list(sex=c("Female", "Male"),
race=c("Black", "Caucasian", "Other"),
tx=c("Drug X", "Placebo")),
units=c(age="years", weight="lbs."))
contents(x)
Now let's create a binary outcome based on the number of visits --- we're interested in what predicts a patient will have more than 10 visits.
x$gt10visits <- factor(ifelse(x$visits <= 10, 0, 1),
labels = c("<= 10 visits", "> 10 visits"))
describe(x$gt10visits)
Now let's fit the logistic regression model:
m1 <- lrm(gt10visits ~ age + race + sex + weight + tx, data = x)
Because we're going to be summarizing and plotting our
lrm
model, we need to define the
datadist
(i.e., data distribution --- the ranges, levels, etc.) of our data.
dd <- datadist(x)
options(datadist = "dd")
NOTE, these two lines of code must be executed when using the
Design
package's
summary.Design()
,
plot.Design()
, and
plot.summary.Design()
functions (as well as others) to summarize of plot any of the
Design
package's modeling functions (e.g.,
ols()
,
lrm()
, and
cph()
).
Let's plot the model:
plot(summary(m1))
Let's make some changes to the previous default plot:
plot(summary(m1,
# use variable labels instead of variable names
# --> must have variable labels defined
# ---> NOTE: vnames= is a summary.Design argument
vnames = "labels"),
# plot only the 95% CI of the ORs
# ---> * must specify both q= and col= *
q = 0.95, col = "gray",
# Plot on the X beta scale but label with anti-logs
log = TRUE)
Based on the plot, we notice that only two of the three race contrasts have been included. Let's work on incorporating the third race contrast into the plot:
# Problem: By default, for a 3-level categorical variable,
# summary generates ORs for 2 comparisons
# (all to reference level)
# Desire: Include the additional contrast
# (i.e., for race, Black:Other)
# Solution: Expand the matrix of ORS generated by summary.Design
# that is used by plot.summary.Design to include
# the additional contrast
# Step 1: Assign the summary including the two default race contrasts
m1summ <- summary(m1, vnames = "labels")
# Step 2: Assign the summary of the third race contrast
# --> Only need the first two rows
race3contrast <- summary(m1, est.all = FALSE, race = "Other",
vnames = "labels")[1:2,]
# Step 3: Splice together the two summaries
# --> insert the third race contrast after the first two
expandedsumm <- rbind(m1summ[1:8, ], race3contrast, m1summ[9:10,])
# Step 4: Modify the attributes of expandedsumm
# --> Class of expandedsumm must be "summary.Design"
# in order for plot to be correct
# --> right now, class(expandedsumm) = "matrix"
# --> however, class(m1summ) = "summary.Design", so
# use its attributes as a template
str(m1summ)
attributes(m1summ)
# Step 4a: Assign the attributes of m1summ
summattr <- attributes(m1summ)
# Step 4b: Modify the dimnames of summattr to include
# the third race contrast (i.e., use the dimnames of expandedsumm)
summattr$dimnames <- attr(expandedsumm, "dimnames")
# NOTE: the attributes() function returns all attributes of an object
# while the attr() function allows you to extract specific (one or more)
# attributes from an object
# NOTE: attr(expandedsumm, "dimnames") <==> attributes(expandedsumm)$dimnames
# Step 4c: Modify the dimensions of summattr to match those of expandedsumm
summattr$dim <- attr(expandedsumm, "dim")
# Step 4d: Assign the attributes of expandedsumm to summattr
attributes(expandedsumm) <- summattr
# Create the OR plot based on the expanded summary
plot(expandedsumm, q = 0.95, col = "gray", log = TRUE)