2011-12-28 14 views
11

tengo algunos datos:R: uso del factor

transaction <- c(1,2,3); 
date <- c("2010-01-31","2010-02-28","2010-03-31"); 
type <- c("debit", "debit", "credit"); 
amount <- c(-500, -1000.97, 12500.81); 
oldbalance <- c(5000, 4500, 17000.81) 
evolution <- data.frame(transaction, date, type, amount, oldbalance, row.names=transaction, stringsAsFactors=FALSE); 
evolution$date <- as.Date(evolution$date, "%Y-%m-%d"); 
evolution <- transform(evolution, newbalance = oldbalance + amount); 
evolution 

Si entro en el comando:

type <- factor(type) 

donde type es variable nominal (categórica), entonces, ¿qué diferencia hace a mi ¿datos?

Gracias

Respuesta

10

Factores contra vectores de caracteres al hacer estadísticas: En términos de hacer estadísticas, no hay diferencia en la forma en que R trata los factores y los vectores de caracteres. De hecho, a menudo es más fácil dejar variables de factores como vectores de caracteres.

Si usted hace una regresión o ANOVA con lm() con un vector de caracteres como una variable categórica que obtendrá los resultados del modelo normal, pero con el mensaje:

Warning message: 
In model.matrix.default(mt, mf, contrasts) : 
    variable 'character_x' converted to a factor 

Factores vs vectores de caracteres cuando se manipulan dataframes: Sin embargo, al manipular marcos de datos, los vectores de caracteres y los factores se tratan de manera muy diferente. Parte de la información sobre las molestias de los factores R & se puede encontrar en el blog de Quantum Forest, R pitfall #3: friggin’ factors.

Es útil usar stringsAsFactors = FALSE al leer datos desde un .csv o .txt usando read.table o read.csv. Como se indicó en otra respuesta, debes asegurarte de que todo en tu vector de caracteres sea coherente, de lo contrario, cada error tipográfico se designará como un factor diferente. Puede usar la función gsub() para corregir errores tipográficos.

Aquí hay un ejemplo trabajado que muestra cómo lm() le da los mismos resultados con un vector de caracteres y un factor.

Una variable aleatoria independiente:

continuous_x <- rnorm(10,10,3) 

Una variable categórica al azar como un vector de caracteres:

character_x <- (rep(c("dog","cat"),5)) 

convertir el vector de caracteres a una variable de factor. factor_x < - as.factor (character_x)

Dale las dos categorías de valores aleatorios:

character_x_value <- ifelse(character_x == "dog", 5*rnorm(1,0,1), rnorm(1,0,2)) 

Crear una relación aleatoria entre las variables indepdent y una variable dependiente

continuous_y <- continuous_x*10*rnorm(1,0) + character_x_value 

comparar la salida de un modelo lineal con la variable de factor y el carácter vector. Tenga en cuenta la advertencia que se proporciona con el vector de caracteres.

summary(lm(continuous_y ~ continuous_x + factor_x)) 
summary(lm(continuous_y ~ continuous_x + character_x)) 
+0

"Es útil usar' stringsAsFactors = TRUE' al leer datos de .csv o .txt usando 'read.table' o' read.csv'. " Tengo curiosidad de por qué? Si "a menudo es más fácil dejar las variables de factores como vectores de caracteres", ¿por qué querría hacer lo opuesto al importar un marco de datos? – landroni

+1

Debería ser stringsAsFactors = FALSE. He arreglado el texto. Gracias por las preguntas –

4

tipo se convertirán de un personaje a un factor. La principal diferencia es que los factores tienen niveles predefinidos. Por lo tanto, su valor solo puede ser uno de esos niveles o NA. Mientras que los personajes pueden ser cualquier cosa.

9

¡Todo depende de la pregunta que haga sobre los datos!

type.c <- c("debit", "debit", "credit") 
type.f <- factor(type.c) 

Aquí type.c es sólo una lista de cadenas de caracteres, mientras que type.f es una lista de factores (si esto es correcto, o es una matriz?)

storage.mode(type.c) 
# [1] "character" 
storage.mode(type.f) 
# [1] "integer" 

cuando un factor variable es creada se ve a través de todos los valores que se han especificado y crea los "niveles" ... tiene una oportunidad única:

levels(type.f) 
# [1] "credit" "debit" 

Entonces, en lugar de almacenar las cadenas de caracteres "débito" "crédito" "mis -spelt debbit "etc ... simplemente almacena es el número entero junto con los niveles ... echar un vistazo a:

str(type.f) 
# Factor w/ 2 levels "credit","debit": 2 2 1 

es decir, en type.c dice c ("débito", "débito", "crédito") y niveles (type.f) dice "crédito" "débito", verá que str (type.f) comienza a enumerar los primeros valores tal como están almacenados, es decir, 2 2 1 ...

Si escribe mal "debitar" y agregar a la lista, y luego haga un nivel (type.f) lo verá como un nuevo nivel ... de lo contrario podría hacer la tabla (type.c).

Cuando solo hay tres elementos en la lista, no importa mucho el volumen de almacenamiento, pero a medida que la lista se alarga, se iniciará "crédito" (6 caracteres) y "cargo" (5 caracteres) ocupa mucho más espacio de almacenamiento que los 4 bytes necesarios para contener un número entero (más el par de bytes). Un pequeño experimento muestra que para un conjunto de type.c seleccionado al azar, el umbral en object.size (type.c)> object.size (type.f) es de aproximadamente 96 elementos.

dc <- c("debit", "credit") 
N <- 300 

# lets store the calculations as a matrix 
# col1 = n 
# col2 = sizeof(character) 
# col3 = sizeof(factors) 
res <- matrix(ncol=3, nrow=N) 

for (i in c(1:N)) { 
    type.c <- sample(dc, i, replace=T) 
    type.f <- factor(type.c) 
    res[i, 1] <- i 
    res[i, 2] <- object.size(type.c) 
    res[i, 3] <- object.size(type.f) 
    cat('N=', i, ' object.size(type.c)=',object.size(type.c), ' object.size(type.f)=',object.size(type.f), '\n') 
} 
plot(res[,1], res[,2], col='blue', type='l', xlab='Number of items in type.x', ylab='bytes of storage') 
lines(res[,1], res[,3], col='red') 
mtext('blue for character; red for factor') 

cat('Threshold at:', min(which(res[,2]>res[,3])), '\n') 

Disculpas por la falta de R'ness ya que pensé que ayudaría con la claridad.