Running Cox.ph model with GAMM mixed models in R - r

I am new in using GAM and splines. I am running a survival model in which I want to model the Time to event with the age of the subjects controlling by two variables. Here is the example using a conventional survival model with coxph:
library(survival)
fit_cox<-coxph(Surv(time, event)~ age+ var1 + var2, data=mydata)
I suspect that the relationship between var1 and var2 with the outcome is not linear and also I am thinking that I can include random effects in my model (moving to mixed effect models gamm).
I have tried this syntax:
library(mgcv)
fit_surv<-Surv(time, event)
fit_gam<-gam(fit_surv ~ age + s(var1) + s(var2), data = mydata, family = cox.ph())
And to include the random effects:
library(gamm4)
fit_gamm <- gamm4(fit_surv ~ age + s(var1) + s(var2), random = ~(1 | ID), data = mydata, family = cox.ph)
My problems are:
1. In fit_gam I do not know how to make a summary of this model and to see the coefficients table and plot the model. This error came to me:
summary(fit_gam)
"Error in Ops.Surv(w, object$y) : Invalid operation on a survival time"
In fit_gamm I could not run the model because some error in syntaxis is made or maybe I could not include a surv? The error is:
"Error in ncol(x) : object 'x' not found"
Thank you in advance!

As mentioned in the comments, simple gaussian frailties (gaussian random intercept) can be specified directly within the mgcv::gam call, e.g. by adding ... + s(ID, bs = "re") + ... to your formula (note that ID has to be a factor variable).
Alternatively, you can transform the data to the so called Piece-wise Exponential Data (PED) format and fit the model using any GA(M)M software, which are then called Piece-wise exponential Additive Mixed Models (PAMM). Here is an example:
library(coxme)
library(mgcv)
library(pammtools)
lung <- lung %>% mutate(inst = as.factor(inst)) %>% na.omit()
## cox model with gaussian frailty
cme <- coxme(Surv(time, status) ~ ph.ecog + (1|inst), data=lung)
## pamm with gaussian frailty
ped <- lung %>% as_ped(Surv(time, status)~., id="id")
pam <- gam(ped_status ~ s(tend) + ph.ecog + s(inst, bs = "re"),
data = ped, family = poisson(), offset = offset)
## visualize random effect:
gg_re(pam)
# compare coxme and pamm estimates:
re <- tidy_re(pam)
plot(cme$frail$inst, re$fit, las=1, xlab="Frailty (cox)", ylab="Frailty (PAM)")
abline(0, 1)
## with gamm4
library(gamm4)
#> Loading required package: Matrix
#> Loading required package: lme4
#>
#> Attaching package: 'lme4'
#> The following object is masked from 'package:nlme':
#>
#> lmList
#> This is gamm4 0.2-5
pam2 <- gamm4(ped_status ~ s(tend) + ph.ecog, random = ~(1|inst),
family = poisson(), offset = ped$offset, data = ped)
lattice::qqmath(ranef(pam2$mer)$inst[, 1])
Created on 2018-12-08 by the reprex package (v0.2.1)

Related

Probing interactions in nlme using the "interactions" package in R

I am running a linear mixed effects models using the "nlme" package looking at stress and lifestyle as predictors of change in cognition over 4 years in a longitudinal dataset. All variables in the model are continuous variables.
I am able to create the model and get the summary statistics using this code:
mod1 <- lme(MS ~ age + sex + edu + GDST1*Time + HLI*Time + GDST1*HLI*Time, random= ~ 1|ID, data=NuAge_long, na.action=na.omit)
summary(mod1)
I am trying to use the "interactions" package to probe the 3-way interaction:
sim_slopes(model = mod1, pred = Time, modx = GDST1, mod2 = HLI, data = NuAge_long)
but am receiving this error:
Error in if (tcol == "df") tcol <- "t val." : argument is of length zero
I am also trying to plot the interaction using the same "interactions" package:
interact_plot(model = mod1, pred = Time, modx = GDST1, mod2 = HLI, data = NuAge_long)
and am receiving this error:
Error in UseMethod("family") : no applicable method for 'family' applied to an object of class "lme"
I can't seem to find what these errors mean and why I'm getting them. Any help would be appreciated!
From ?interactions::sim_slopes:
The function is tested with ‘lm’, ‘glm’,
‘svyglm’, ‘merMod’, ‘rq’, ‘brmsfit’, ‘stanreg’ models. Models
from other classes may work as well but are not officially
supported. The model should include the interaction of
interest.
Note this does not include lme models. On the other hand, merMod models are those generated by lme4::[g]lmer(), and as far as I can tell you should be able to fit this model equally well with lmer():
library(lme4)
mod1 <- lmer(MS ~ age + sex + edu + GDST1*Time + HLI*Time + GDST1*HLI*Time
+ (1|ID), data=NuAge_long)
(things will get harder if you want to specify correlation structures, e.g. correlation = corAR1(), which works for lme() but not lmer() ...)

Goodness of Fit statistic Tobit model

I have estimated a Tobit model using the censReg package, along with the censReg function. Alternatively, the same Tobit model is estimated using the tobit function in the AER package.
Now, I really like to have some goodness of fit statistic, such as the Pseudo-R2. However, whenever I try to estimate this, the output returns as NA. For example:
Tobit <- censReg(Listing$occupancy_rate ~ ., left = -Inf, right = 1, data = Listing)
PseudoR2(Tobit, which = "McFadden")
[1] NA
So far, I have only seen reported Pseudo-R2's when people use Stata. Does anyone know how to estimate it in R?
Alternatively, Tobit estimates the (log)Sigma, which is basically the standard deviation of the residuals. Could I use this to calculate the R2?
All help is really appreciated.
You can use DescTools package to calculate PseudoR2. You have not provided any sample data. So, it is hard for me to run your model. I am using a default dataset like
library(DescTools)
r.glm <- glm(Survived ~ ., data=Untable(Titanic), family=binomial)
PseudoR2(r.glm, c("McFadden"))
For your model, you can use something like
library(AER)
data("Affairs", package = "AER")
fm.tobit <- tobit(affairs ~ age + yearsmarried + religiousness + occupation + rating,
data = Affairs)
#Create a function for pseudoR2 calculation
pseudoR2 <- function(obj) 1 - as.vector(logLik(obj)/logLik(update(obj, . ~ 1)))
pseudoR2(fm.tobit)
#>[1] 0.05258401
Or using censReg as you have used
library(censReg)
data("Affairs", package = "AER")
estResult <- censReg(affairs ~ age + yearsmarried + religiousness +
occupation + rating, data = Affairs)
summary(estResult)
pseudoR2(estResult)
#>[1] 0.05258401
You can find the details about pseudoR2 in the following link
R squared in logistic regression

Obtaining individual slopes from an lme4 object in R

I'm new to lme4 package in R. In my example below, I was wondering if it might be possible to obtain the gender slopes (i.e., differences) for each dep after fitting my glmer model?
dat <- data.frame(dep = rep(LETTERS[1:6],each=2), gender = rep(c("Ma","Fe"),6),
admit=c(512,89,353,17,120,202,138,131,53,94,22,24),
reject=c(313,19,207,8,205,391,279,244,138,299,351,317))
lme4::glmer(cbind(admit,reject) ~ gender+dep + (gender|dep), data=dat, family=binomial)
In lme4 you can get the estimated slopes from ranef, but in your model you will need to sum the global and unit specific terms, as in the example below.
library(lme4)
dat <- data.frame(dep = rep(LETTERS[1:6],each=2), gender = rep(c("Ma","Fe"),6),
admit=c(512,89,353,17,120,202,138,131,53,94,22,24),
reject=c(313,19,207,8,205,391,279,244,138,299,351,317))
mod1 <- glmer(cbind(admit,reject) ~ gender+dep + (gender|dep), data=dat, family=binomial)
summary(mod1)
ran_gender <- ranef(mod1)$dep
fe_mod1 <- fixef(mod1)
slopes <- fe_mod1[[2]] + ran_gender[,2]
slopes

Getting estimated means after multiple imputation using the mitml, nlme & geepack R packages

I'm running multilevel multiple imputation through the package mitml (using the panimpute() function) and am fitting linear mixed models and marginal models through the packages nlme and geepack and the mitml:with() function.
I can get the estimates, p-values etc for those through the testEstimates() function but I'm also looking to get estimated means across my model predictors. I've tried the emmeans package, which I normally use for getting estimated means when running nlme & geepack without multiple imputation but doing so emmeans tell me "Can't handle an object of class “mitml.result”".
I'm wondering is there a way to get pooled estimated means from the multiple imputation analyses I've run?
The data frames I'm analyzing are longitudinal/repeated measures and in long format. In the linear mixed model I want to get the estimated means for a 2x2 interaction effect and in the marginal model I'm trying to get estimated means for the 6 levels of 'time' variable. The outcome in all models is continuous.
Here's my code
# mixed model
fml <- Dep + time ~ 1 + (1|id)
imp <- panImpute(data=Data, formula=fml, n.burn=50000, n.iter=5000, m=100, group = "treatment")
summary(imp)
plot(imp, trace="all")
implist <- mitmlComplete(imp, "all", force.list = TRUE)
fit <- with(implist, lme(Dep ~ time*treatment, random = ~ 1|id, method = "ML", na.action = na.exclude, control = list(opt = "optim")))
testEstimates(fit, var.comp = TRUE)
confint.mitml.testEstimates(testEstimates(fit, var.comp = TRUE))
# marginal model
fml <- Dep + time ~ 1 + (1|id)
imp <- panImpute(data=Data, formula=fml, n.burn=50000, n.iter=5000, m=100)
summary(imp)
plot(imp, trace="all")
implist <- mitmlComplete(imp, "all", force.list = TRUE)
fit <- with(implist, geeglm(Dep ~ time, id = id, corstr ="unstructured"))
testEstimates(fit, var.comp = TRUE)
confint.mitml.testEstimates(testEstimates(fit, var.comp = TRUE))
is there a way to get pooled estimated means from the multiple imputation analyses I've run?
This is not a reprex without Data, so I can't verify this works for you. But emmeans provides support for mira-class (lists of) models in the mice package. So if you fit your model in with() using the mids rather than mitml.list class object, then you can use that to obtain marginal means of your outcome (and any contrasts or pairwise comparisons afterward).
Using example data found here, which uncomfortably loads an external workspace:
con <- url("https://www.gerkovink.com/mimp/popular.RData")
load(con)
## imputation
library(mice)
ini <- mice(popNCR, maxit = 0)
meth <- ini$meth
meth[c(3, 5, 6, 7)] <- "norm"
pred <- ini$pred
pred[, "pupil"] <- 0
imp <- mice(popNCR, meth = meth, pred = pred, print = FALSE)
## analysis
library(lme4) # fit multilevel model
mod <- with(imp, lmer(popular ~ sex + (1|class)))
library(emmeans) # obtain pooled estimates of means
(em <- emmeans(mod, specs = ~ sex) )
pairs(em) # test comparison

Plot Effects of Variables in Interaction Terms

I would like to plot the effects of variables in interaction terms, using panel data and a FE model.
I have various interaction effects in my equation, for example this one here:
FIXED1 <- plm(GDPPCgrowth ~ FDI * PRIVCR, data = dfp)
I can only find solutions for lm, but not for plm.
So on the x-axis there should be PRIVCR and on the y-axis the effect of FDI on growth.
Thank you for your help!
Lisa
I am not aware of a package that supports plm objects directly. As you are asking for FE models, you can just take an LSDV approach for FE and do the estimation by lm to get an lm object which works with the effects package. Here is an example for the Grunfeld data:
library(plm)
library(effects)
data("Grunfeld", package = "plm")
mod_fe <- plm(inv ~ value + capital + value:capital, data = Grunfeld, model = "within")
Grunfeld[ , "firm"] <- factor(Grunfeld[ , "firm"]) # needs to be factor in the data NOT in the formula [required by package effects]
mod_lsdv <- lm(inv ~ value + capital + value:capital + firm, data = Grunfeld)
coefficients(mod_fe) # estimates are the same
coefficients(mod_lsdv) # estimates are the same
eff_obj <- effects::Effect(c("value", "capital"), mod_lsdv)
plot(eff_obj)

Resources