6 votos

¿Cómo se pueden elegir automáticamente los niveles de los factores en R para maximizar el número de coeficientes positivos en un modelo de regresión?

Estoy realizando una regresión lineal simple (términos de primer orden) sobre datos que tienen varias variables categóricas (es decir, factores), y a menudo se desea que para cada factor, uno de los niveles no añada nada al regresor, y los otros niveles añadan valores positivos al regresor. Sin embargo, cuando realizo un análisis de regresión, a menudo obtengo muchos coeficientes negativos.

¿Existe una no manual ¿Cómo puedo elegir qué niveles de un factor deben utilizarse como variables regresoras para maximizar el número de coeficientes positivos en la ecuación? En otras palabras, ¿cómo puedo conseguir que R haga esta tarea (algo tediosa) por mí?

3voto

Tom Future Puntos 563

Gracias al comentario de whuber, y a la respuesta de Seb, he montado la siguiente función que creo que hace lo que quiero. Espero que le sea útil a alguien. Los comentarios son bienvenidos.

# take a dataframe, and re-level it such that the levels of the factors are
# assigned positive coefficients by lm()
# NOTE: this currently only works for model-forms that don't include
#       interaction terms.
auto_relevel <- function(df, model_form)
{
    # get list of categorical variables in df
    catvar_indices <- get_catvar_indices(df)

    # loop over categorical variables
    df_colnames <- attr(df, 'names')
    model_form_zeroicept <- paste(model_form, "- 1")
    for (i in catvar_indices) {
        catvar_name = df_colnames[i]
        all_levels = attr(df[[i]], "levels")
        temp_model <- lm(model_form_zeroicept, data=df)

        # If at least one of the levels' coefficients is less than zero, then
        # choose the one w/min coeff to be the new base-level

        # put a space after catvar_name so that it doesn't match longer level-names
        catvar_name <- paste(catvar_name, " ", sep="")
        factors <- grep(catvar_name, names(coef(temp_model)))
        coeffs <- coef(temp_model)[factors]
        # remove NA's from coeffs
        coeffs2 <- coeffs[! is.na(coeffs)]

        if (any(coeffs2 < 0)) {            
            # find out where this factor is in *all_levels*
            chosen_level_name <- names(coeffs2)[which(coeffs2==min(coeffs2))]
            stripped_level_name <- unlist(strsplit(chosen_level_name," "))[2] # strip factor name
            # add an initial space (to match all_levels)
            stripped_level_name <- paste(" ", stripped_level_name, sep="")
            min_level_index <- which(all_levels == stripped_level_name)
            df[[i]] <- relevel(df[[i]], ref=min_level_index)
        }
    }

    return(df)
}

2voto

Daniel Moura Puntos 4298

Aquí hay un intento de hacer lo que querías.

 # Setting up some sample data
 require(dummies)
 df <- data.frame(categorial=rep(c(1,2,3), each=20), x=rnorm(60))
 flevels <- dummy(df$categorial)
 df$categorial <- factor(df$categorial)

 df$y=20 + df$x*3 + flevels%*%c(3,1,2) + rnorm(60)*2

Utilizo una regresión para obtener el nivel mínimo del factor y luego reordenarlo:

 # Now we start with trying to find the minimum cateogry. However, note that this does not work in every context!
 summary(helpreg <- lm(y~x+factor(categorial) - 1, data=df))

     Coefficients:
                         Estimate Std. Error t value Pr(>|t|)    
     x                     2.9944     0.2334   12.83   <2e-16 ***
     factor(categorial)1  22.9640     0.4472   51.35   <2e-16 ***
     factor(categorial)2  21.0720     0.4390   48.00   <2e-16 ***
     factor(categorial)3  22.1300     0.4364   50.71   <2e-16 ***

Entonces empiezo a ordenar lo mínimo:

 factors <- grep('categorial', names(coef(helpreg))) # --- replace categorial with your variable name

 minimumf <- which(coef(helpreg)[factors]==min(coef(helpreg)[factors]))

A continuación, se renivela

 df$categorial <- relevel(df$categorial, ref=minimumf)

Y en mi caso funciona - probablemente también te funcione a ti....

 summary(lm(y~x+factor(categorial), data=df))

                           Estimate Std. Error t value Pr(>|t|)    
       (Intercept)          21.0720     0.4390  48.003  < 2e-16 ***
       x                     2.9944     0.2334  12.828  < 2e-16 ***
       factor(categorial)1   1.8920     0.6341   2.984  0.00421 ** 
       factor(categorial)3   1.0580     0.6193   1.708  0.09310 . 

Los comentarios, por supuesto, son muy apreciados.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X