¿Se pregunta si alguien se ha encontrado con un paquete / función en R que combine niveles de un factor cuya proporción de todos los niveles en un factor sea inferior a algún umbral? Específicamente, uno de los primeros pasos en la preparación de datos que realizo es colapsar niveles dispersos de factores (digamos en un nivel llamado 'Otro') que no constituyen al menos, digamos, 2% del total. Esto se hace sin supervisión y se hace cuando el objetivo es modelar alguna actividad en marketing (no detección de fraude, donde esos casos muy pequeños podrían ser extremadamente importantes). Estoy buscando una función que colapsará los niveles hasta que se alcance alguna proporción umbral.
ACTUALIZAR:
Gracias a estas excelentes sugerencias, escribí una función con bastante facilidad. Sin embargo, me di cuenta de que era posible colapsar los niveles con una proporción <el mínimo y todavía tener ese nivel recodificado ser <el mínimo, lo que requiere la adición del nivel más bajo con la proporción> el mínimo. Probablemente puede ser más eficiente, pero parece funcionar. La próxima mejora sería descubrir cómo capturar las "reglas" para aplicar la lógica de colapso a los nuevos datos (un conjunto de validación o datos futuros).
collapseFactors<- function(tableName,minPercent=5,fillIn ="RECODED" )
{
for (i in 1:ncol(tableName))
{
if(is.factor(tableName[,i]) == TRUE) #process just factors
{
sortedTable<-sort(prop.table(table(tableName[,i])))
numberToCollapse<-length(sortedTable[sortedTable<(minPercent/100)])
if (sum(sortedTable[1:numberToCollapse])<(minPercent/100))
{
numberToCollapse=numberToCollapse+1 #add next level if < minPercent
}
if(numberToCollapse>1) #if not >1 then nothing to collapse
{
lf <- names(sortedTable[1:numberToCollapse])
levels(tableName[,i])[levels(tableName[,i]) %in% lf] <- fillIn
}
}#end if a factor
}#end for loop
return(tableName)
}#end function
fuente
Respuestas:
Parece que es solo una cuestión de "reenviar" el factor; no es necesario calcular sumas parciales o hacer una copia del vector original. P.ej,
Aquí, los niveles de factores originales se distribuyen de la siguiente manera:
y luego se convierte
Puede estar convenientemente envuelto en una función. Hay una
combine_factor()
función en el paquete de remodelación , así que supongo que también podría ser útil.Además, como parece interesado en la minería de datos, puede echar un vistazo al paquete de intercalación . Tiene muchas características útiles para el preprocesamiento de datos, incluidas funciones
nearZeroVar()
que permiten marcar predictores con una distribución muy desequilibrada de los valores observados (consulte la viñeta, datos de ejemplo, funciones de preprocesamiento, visualizaciones y otras funciones , p. 5, por ejemplo de uso).fuente
a[as.character(a) %in% lf] <- lf[1]; a <- factor(droplevels(a), labels=c("Other",LETTERS[3:5]))
.El único problema con la respuesta de Christopher es que mezclará el orden original del factor. Aquí está mi solución:
¿Dónde
change.levels
está la siguiente función? Lo escribí hace algún tiempo, por lo que sospecho que podría haber mejores formas de lograr lo que hace.fuente
Escribí una función rápida que logrará este objetivo. Soy un usuario novato de R, por lo que puede ser lento con tablas grandes.
Como ejemplo de ello en acción:
fuente