Estandarizar las columnas de datos en R

Tengo un conjunto de datos llamado spam que contiene 58 columnas y aproximadamente 3500 filas de datos relacionados con mensajes de spam.

Planeo ejecutar alguna regresión lineal en este conjunto de datos en el futuro, pero me gustaría hacer un preprocesamiento de antemano y estandarizar las columnas para tener una media cero y una unidad de varianza.

Me han dicho que la mejor manera de hacerlo es con R, por lo que me gustaría preguntar cómo puedo lograr la normalización con R ? Ya tengo los datos cargados correctamente y solo estoy buscando algunos paquetes o métodos para realizar esta tarea.

Tengo que suponer que quisiste decir que querías una media de 0 y una desviación estándar de 1. Si tus datos están en un dataframe y todas las columnas son numéricas, puedes simplemente llamar a la función de scale en los datos para hacer lo que quieras .

 dat < - data.frame(x = rnorm(10, 30, .2), y = runif(10, 3, 5)) scaled.dat <- scale(dat) # check that we get mean of 0 and sd of 1 colMeans(scaled.dat) # faster version of apply(scaled.dat, 2, mean) apply(scaled.dat, 2, sd) 

El uso de funciones integradas es elegante. Como este gato:

enter image description here

Al darme cuenta de que la pregunta es antigua y que se acepta una respuesta, proporcionaré otra respuesta para referencia.

scale está limitada por el hecho de que escala todas las variables . La siguiente solución permite escalar solo nombres de variables específicos mientras se conservan otras variables sin cambios (y los nombres de las variables se pueden generar dinámicamente):

 library(dplyr) set.seed(1234) dat < - data.frame(x = rnorm(10, 30, .2), y = runif(10, 3, 5), z = runif(10, 10, 20)) dat dat2 <- dat %>% mutate_each_(funs(scale(.) %>% as.vector), vars=c("y","z")) dat2 

que me da esto:

 > dat xyz 1 29.75859 3.633225 14.56091 2 30.05549 3.605387 12.65187 3 30.21689 3.318092 13.04672 4 29.53086 3.079992 15.07307 5 30.08582 3.437599 11.81096 6 30.10121 4.621197 17.59671 7 29.88505 4.051395 12.01248 8 29.89067 4.829316 12.58810 9 29.88711 4.662690 19.92150 10 29.82199 3.091541 18.07352 

y

 > dat2 < - dat %>% mutate_each_(funs(scale(.) %>% as.vector), > vars=c("y","z")) > dat2 xyz 1 29.75859 -0.3004815 -0.06016029 2 30.05549 -0.3423437 -0.72529604 3 30.21689 -0.7743696 -0.58772361 4 29.53086 -1.1324181 0.11828039 5 30.08582 -0.5946582 -1.01827752 6 30.10121 1.1852038 0.99754666 7 29.88505 0.3283513 -0.94806607 8 29.89067 1.4981677 -0.74751378 9 29.88711 1.2475998 1.80753470 10 29.82199 -1.1150515 1.16367556 

EDIT : respondió el comentario de Julian: el resultado de la scale es la matriz Nx1, por lo que idealmente deberíamos agregar un as.vector para as.vector a convertir el tipo de matriz en un vector. Gracias Julian!

Esto tiene 3 años. Aún así, siento que debo agregar lo siguiente:

La normalización más común es la transformación z , donde se resta la media y se divide por la desviación estándar de la variable. El resultado tendrá mean = 0 y sd = 1.

Para eso, no necesitas ningún paquete.

 zVar < - (myVar - mean(myVar)) / sd(myVar) 

Eso es.

El paquete ‘Caret’ proporciona métodos para preprocesar datos (por ejemplo, centrado y escalado). También podría usar el siguiente código:

 library(caret) # Assuming goal class is column 10 preObj < - preProcess(data[, -10], method=c("center", "scale")) newData <- predict(preObj, data[, -10]) 

Más detalles: http://www.inside-r.org/node/86978

También puede normalizar fácilmente los datos utilizando datos. Función de normalización en el paquete clusterSim. Proporciona un método diferente de normalización de datos.

  data.Normalization (x,type="n0",normalization="column") 

Argumentos

X
vector, matriz o tipo de conjunto de datos
tipo de normalización: n0 – sin normalización

n1 – estandarización ((x-mean) / sd)

n2 – estandarización posicional ((x-mediana) / enojada)

n3 – unitización ((x-media) / rango)

n3a – unitización posicional ((x-mediana) / rango)

n4 – unitización con mínimo cero ((x-min) / rango)

n5 – normalización en el rango < -1,1> ((x-media) / max (abs (x-media)))

n5a – normalización posicional en rango < -1,1> ((x-mediana) / max (abs (x-mediana)))

n6 – transformación del cociente (x / sd)

n6a – transformación del cociente posicional (x / enojado)

n7 – transformación del cociente (x / rango)

n8 – transformación del cociente (x / max)

n9 – transformación del cociente (x / media)

n9a – transformación del cociente posicional (x / mediana)

n10 – transformación del cociente (x / sum)

n11 – transformación del cociente (x / sqrt (SSQ))

n12 – normalización ((x-mean) / sqrt (sum ((x-mean) ^ 2)))

n12a – normalización posicional ((x-mediana) / sqrt (sum ((x-mediana) ^ 2)))

n13 – normalización con cero siendo el punto central ((x-rango medio) / (rango / 2))

normalización
“columna” – normalización por variable, “fila” – normalización por objeto

Cuando utilicé la solución indicada por Dason, en lugar de obtener un dataframe como resultado, obtuve un vector de números (los valores escalados de mi df).

En caso de que alguien esté teniendo el mismo problema, debe agregar as.data.frame () al código, así:

 df.scaled < - as.data.frame(scale(df)) 

¡Espero que esto sea útil para personas que tienen el mismo problema!

Con dplyr v0.7.4 todas las variables se pueden escalar usando mutate_all() :

 library(dplyr) #> #> Attaching package: 'dplyr' #> The following objects are masked from 'package:stats': #> #> filter, lag #> The following objects are masked from 'package:base': #> #> intersect, setdiff, setequal, union library(tibble) set.seed(1234) dat < - tibble(x = rnorm(10, 30, .2), y = runif(10, 3, 5), z = runif(10, 10, 20)) dat %>% mutate_all(scale) #> # A tibble: 10 x 3 #> xyz #>    #> 1 -0.827 -0.300 -0.0602 #> 2 0.663 -0.342 -0.725 #> 3 1.47 -0.774 -0.588 #> 4 -1.97 -1.13 0.118 #> 5 0.816 -0.595 -1.02 #> 6 0.893 1.19 0.998 #> 7 -0.192 0.328 -0.948 #> 8 -0.164 1.50 -0.748 #> 9 -0.182 1.25 1.81 #> 10 -0.509 -1.12 1.16 

Las variables específicas se pueden excluir usando mutate_at() :

 dat %>% mutate_at(scale, .vars = vars(-x)) #> # A tibble: 10 x 3 #> xyz #>    #> 1 29.8 -0.300 -0.0602 #> 2 30.1 -0.342 -0.725 #> 3 30.2 -0.774 -0.588 #> 4 29.5 -1.13 0.118 #> 5 30.1 -0.595 -1.02 #> 6 30.1 1.19 0.998 #> 7 29.9 0.328 -0.948 #> 8 29.9 1.50 -0.748 #> 9 29.9 1.25 1.81 #> 10 29.8 -1.12 1.16 

Creado en 2018-04-24 por el paquete reprex (v0.2.0).

De nuevo, aunque esta es una vieja pregunta, ¡es muy relevante! Y he encontrado una manera simple de normalizar ciertas columnas sin necesidad de ningún paquete:

 normFunc < - function(x){(x-mean(x, na.rm = T))/sd(x, na.rm = T)} 

Por ejemplo

 x< -rnorm(10,14,2) y<-rnorm(10,7,3) z<-rnorm(10,18,5) df<-data.frame(x,y,z) df[2:3] <- apply(df[2:3], 2, normFunc) 

Verá que las columnas yy z se han normalizado. No se necesitan paquetes 🙂

Antes de que encontrara este hilo, tuve el mismo problema. Tenía tipos de columnas dependientes del usuario, así que escribí un ciclo for revisarlas y obtener las columnas necesarias ‘ scale ‘. Probablemente haya mejores formas de hacerlo, pero esto resolvió el problema muy bien:

  for(i in 1:length(colnames(df))) { if(class(df[,i]) == "numeric" || class(df[,i]) == "integer") { df[,i] < - as.vector(scale(df[,i])) } } 

as.vector es una parte necesaria, porque resultó que scale hace rownames x 1 matrix, que generalmente no es lo que quiere tener en su data.frame .

La escala se puede usar tanto para el dataframe completo como para columnas específicas. Para columnas específicas, se puede usar el siguiente código:

 trainingSet[, 3:7] = scale(trainingSet[, 3:7]) # For column 3 to 7 trainingSet[, 8] = scale(trainingSet[, 8]) # For column 8 

Marco de datos completo

 trainingSet < - scale(trainingSet) 

Use el paquete “recommenderlab”. Descargue e instale el paquete. Este paquete tiene un comando “Normalizar” en construido. También le permite elegir uno de los muchos métodos para la normalización, a saber, ‘centro’ o ‘Z-score’. Siga el siguiente ejemplo:

 ## create a matrix with ratings m < - matrix(sample(c(NA,0:5),50, replace=TRUE, prob=c(.5,rep(.5/6,6))),nrow=5, ncol=10, dimnames = list(users=paste('u', 1:5, sep=”), items=paste('i', 1:10, sep=”))) ## do normalization r <- as(m, "realRatingMatrix") #here, 'centre' is the default method r_n1 <- normalize(r) #here "Z-score" is the used method used r_n2 <- normalize(r, method="Z-score") r r_n1 r_n2 ## show normalized data image(r, main="Raw Data") image(r_n1, main="Centered") image(r_n2, main="Z-Score Normalization") 

El paquete dplyr tiene dos funciones que hacen esto.

 > require(dplyr) 

Para mutar columnas específicas de una tabla de datos, puede usar la función mutate_at() . Para mutar todas las columnas, puede usar mutate_all .

El siguiente es un breve ejemplo para usar estas funciones para estandarizar datos.

Mutear columnas específicas:

 dt = data.table(a = runif(3500), b = runif(3500), c = runif(3500)) dt = data.table(dt %>% mutate_at(vars("a", "c"), scale)) # can also index columns by number, eg, vars(c(1,3)) > apply(dt, 2, mean) abc 1.783137e-16 5.064855e-01 -5.245395e-17 > apply(dt, 2, sd) abc 1.0000000 0.2906622 1.0000000 

Mutar todas las columnas:

 dt = data.table(a = runif(3500), b = runif(3500), c = runif(3500)) dt = data.table(dt %>% mutate_all(scale)) > apply(dt, 2, mean) abc -1.728266e-16 9.291994e-17 1.683551e-16 > apply(dt, 2, sd) abc 1 1 1