سؤال

I'm writing a function that accepts a full and a reduced glm object to summarize interaction results for a variable of interest varofint and the interaction variable interaction_var (by performing a lrtest and using svycontrast on the full object to extract results for varofint for each level of interaction_var). Sample data:

x <- data.frame(outcome=rbinom(100,1,.3),varofint=rnorm(100), interaction_var=sample(letters[1:3],100,replace=TRUE))

reduced <- glm(outcome~varofint+interaction_var,data=x)
full <- glm(outcome~varofint*interaction_var,data=x)

I'd like to know the best way to extract a reference category for said (full) glm model. I could obviously do something like

levels(full$data$interaction_var)[1]

but would this be a "safe" method to extract a reference category given inputs to the contrasts argument? It seems like, given the option to select SAS contrast, this method could produce a level of interactionv_var that isn't the one used as a reference category in the model. Would the following be safer?

mf <- model.frame(full)
setdiff(rownames(contrasts(mf[, "interaction_var"])), colnames(contrasts(mf[, "interaction_var"])))

or similarly

names(which(apply(contrasts(mf[, "interaction_var"]),1,function(.v){all(.v==0)})))

Am I missing a simpler way to extract the reference category?

هل كانت مفيدة؟

المحلول

Here is a function for this task:

refCat <- function(model, var) {
  cs <- attr(model.matrix(model), "contrasts")[[var]]
  if (is.character(cs)) {
    if (cs == "contr.treatment")
      ref <- 1
    else stop("No treatment contrast")
  }  
  else {
    zeroes <- !cs
    ones <- cs == 1
    stopifnot(all(zeroes | ones))
    cos <- colSums(ones)
    stopifnot(all(cos == 1))
    ros <- rowSums(ones)
    stopifnot(sum(!ros) == 1 && sum(ros) != ncol(cs))
    ref <- which(!ros)
  }
  return(levels(model$data[[var]])[ref])  
}    

The function will stop if the variable var is not represented as treatment contrasts.

Examples:

refCat(reduced, "interaction_var")
# [1] "a"
refCat(full, "interaction_var")
# [1] "a"

نصائح أخرى

Bit late, but dummy.coef() could work... the first value in each variable element of its output is the reference category.

# R 4.0.0 data.frame() does not produce factors
x <- data.frame(
  outcome = rbinom(100, 1, .3),
  varofint = rnorm(100),
  interaction_var = sample(letters[1:3], 100, replace = TRUE),
  stringsAsFactors = TRUE
)
reduced <- glm(outcome ~ varofint + interaction_var, data = x)
full <- glm(outcome ~ varofint * interaction_var, data = x)

d <- dummy.coef(full)
d
# Full coefficients are 
#                                                                 
# (Intercept):                    0.310136                        
# varofint:                    -0.07247677                        
# interaction_var:                       a           b           c
#                               0.00000000  0.07017833 -0.05891015
# varofint:interaction_var:              a           b           c
#                               0.00000000 -0.14824179 -0.04123618

d$interaction_var
#           a           b           c 
#  0.00000000  0.07017833 -0.05891015 
d$interaction_var[1]
# a 
# 0 
names(d$interaction_var[1])
# [1] "a"
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top