Family.RmdThis vignette accompanies the Results section of the RobinCar Family paper.
##
## Attaching package: 'RobinCar2'
## The following object is masked from 'package:base':
##
## table
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
Data Manipulation
Creates continuous and binary outcomes, and does simple data manipulations.
# Data are from the speff2trial package
data <- tibble(speff2trial::ACTG175)
data <- data %>% mutate(
# Create continuous and binary outcomes
y_cont = cd420 - cd40,
y_bin = as.numeric((y_cont / cd40) > 0.5)
) %>% filter(
# Focus on two treatment arms
arms %in% c("0", "1")
) %>% mutate(
# Factor variables for treatment
# and stratification variable
arms = factor(arms),
strat = factor(strat)
)Linear Adjustment
The following shows a linear model with treatment-by-covariate interactions, including strata as covariates, and using the four covariates of weight, hemophilia status, and prior use of non-zidovudine antiretroviral therapy. These specifications ensure that the covariate adjustment has guaranteed efficiency gain (asymptotically).
robin_lm(
y_cont ~ arms * (strat + wtkg + hemo + oprior),
treatment = arms ~ pb(strat),
data=data)## Model : y_cont ~ arms * (strat + wtkg + hemo + oprior)
## Randomization: arms ~ pb(strat) ( Permuted-Block )
## Variance Type: vcovG
## Marginal Mean:
## Estimate Std.Err 2.5 % 97.5 %
## 0 -16.9304 4.4915 -25.7336 -8.1273
## 1 54.0531 6.2848 41.7352 66.3710
##
## Contrast : h_diff
## Estimate Std.Err Z Value Pr(>|z|)
## 1 v.s. 0 70.984 7.673 9.2511 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Generalized Linear Models
For the binary outcome, we can use a logistic regression model instead.
robin_glm(
y_bin ~ arms * (wtkg + hemo + oprior),
treatment = arms ~ pb(strat),
family = binomial(link = "logit"),
contrast = "risk_ratio",
data = data
)## Warning in robin_glm(y_bin ~ arms * (wtkg + hemo + oprior), treatment = arms ~
## : Consider using the log transformation `log_odds_ratio` and `log_risk_ratio`
## to replace `odds_ratio` and `risk_ratio` to improve the performance of normal
## approximation.
## Model : y_bin ~ arms * (wtkg + hemo + oprior)
## Randomization: arms ~ pb(strat) ( Permuted-Block )
## Variance Type: vcovG
## Marginal Mean:
## Estimate Std.Err 2.5 % 97.5 %
## 0 0.0496651 0.0092998 0.0314378 0.0679
## 1 0.1828118 0.0168988 0.1496908 0.2159
##
## Contrast : risk_ratio
## Estimate Std.Err Z Value Pr(>|z|)
## 1 v.s. 0 3.68089 0.76609 3.4994 0.0004662 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Rather than a linear contrast, we can instead estimate a risk ratio. This does not change the marginal mean estimates, but it changes the contrast estimates (and p-values).
robin_glm(
y_bin ~ arms * (strat + wtkg + hemo + oprior),
treatment = arms ~ pb(strat),
family = binomial(link = "logit"),
contrast = "log_risk_ratio",
data=data
)## Model : y_bin ~ arms * (strat + wtkg + hemo + oprior)
## Randomization: arms ~ pb(strat) ( Permuted-Block )
## Variance Type: vcovG
## Marginal Mean:
## Estimate Std.Err 2.5 % 97.5 %
## 0 0.0493622 0.0093041 0.0311264 0.0676
## 1 0.1835664 0.0168944 0.1504539 0.2167
##
## Contrast : log_risk_ratio
## Estimate Std.Err Z Value Pr(>|z|)
## 1 v.s. 0 1.31339 0.20904 6.2831 3.318e-10 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Mantel-Haenszel
RobinCar includes functions for robust Mantel-Haenszel estimation. Here we create a new variable that is the interaction of prior use of non-zidovudine antiretroviral therapy and hemophilia status, and use that as the stratification variable.
By default, the function uses the average treatment effect as the estimand of interest. Specifying the estimand argument as “MH” does not change the estimate, but it does change the standard error calculation.
The MH function in RobinCar is only valid for simple randomization.
data <- data %>% mutate(
X=interaction(oprior, hemo)
)
robincar_mh(
data, "arms", "y_bin",
strata_cols=c("oprior", "hemo")
)## Treatment group contrasts based on ATE
## Estimand: ATE
## Stratified by oprior, hemo
## SE calculated via modified Greenland's estimator
##
## Contrasts:
## # A tibble: 1 × 4
## contrast estimate se `pval (2-sided)`
## <chr[1d]> <dbl> <dbl> <dbl>
## 1 treat 1 - 0 0.134 0.0193 3.83e-12
Survival Analysis
For a survival outcome with right-censoring, we can use the RobinCar2
function robin_surv to do a covariate-adjusted, stratified
log-rank test.
surv <- robin_surv(
Surv(days, cens) ~ wtkg + oprior + hemo + strat,
treatment = arms ~ pb(strat),
data = data
)
surv## Model : Surv(days, cens) ~ wtkg + oprior + hemo + strat
## Randomization: arms ~ pb(strat) (Permuted-Block)
## Covariates adjusted for: wtkg, oprior, hemo, strat (including interactions with arms)
##
## Contrast : Covariate-adjusted Log Hazard Ratio
##
## Estimate Std.Err Z Value Pr(>|z|)
## 1 v.s. 0 -0.68785 0.12237 -5.6209 1.9e-08 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Test : Covariate-adjusted Log-Rank
##
## Test Stat. Pr(>|z|)
## 1 v.s. 0 -5.7444 9.223e-09 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
You can use the table function to see the number of
events and number at-risk
table(surv)## Number of patients and events per treatment arm:
## arms Patients Events
## 1 0 532 181
## 2 1 522 103