2012-04-23 4 views
31

Tengo una variable explicativa que se centra usando scale() que se utiliza para predecir una variable de respuesta:transformación retrospectiva `escala()` para el trazado

d <- data.frame(
    x=runif(100), 
    y=rnorm(100) 
) 

d <- within(d, s.x <- scale(x)) 

m1 <- lm(y~s.x, data=d) 

me gustaría trazar los valores previstos, pero utilizando el escala original de x en lugar de la escala centrada. ¿Hay alguna manera de ordenar la transición inversa o la escala inversa s.x?

Gracias!

Respuesta

38

echar un vistazo a:

attributes(d$s.x) 

d$s.x * attr(d$s.x, 'scaled:scale') + attr(d$s.x, 'scaled:center') 

por ejemplo:

> x <- 1:10 
> s.x <- scale(x) 
> s.x 
      [,1] 
[1,] -1.4863011 
[2,] -1.1560120 
[3,] -0.8257228 
[4,] -0.4954337 
[5,] -0.1651446 
[6,] 0.1651446 
[7,] 0.4954337 
[8,] 0.8257228 
[9,] 1.1560120 
[10,] 1.4863011 
attr(,"scaled:center") 
[1] 5.5 
attr(,"scaled:scale") 
[1] 3.02765 
> s.x * attr(s.x, 'scaled:scale') + attr(s.x, 'scaled:center') 
     [,1] 
[1,] 1 
[2,] 2 
[3,] 3 
[4,] 4 
[5,] 5 
[6,] 6 
[7,] 7 
[8,] 8 
[9,] 9 
[10,] 10 
attr(,"scaled:center") 
[1] 5.5 
attr(,"scaled:scale") 
[1] 3.02765 
+1

buena respuesta de 1 Si el 'attr (sx, 'escalado: Centro')' 'ser attr (d $ sx, 'escalado: centro') '? –

+0

@TylerRinker Gracias, debería. ¡Fijo! – Justin

+1

Gran respuesta Justin. Muchas gracias. Y gracias a Tyler Rinker por notar el error tipográfico. – smillig

12

Para una trama de datos o matriz:

set.seed(1) 
x = matrix(sample(1:12), ncol= 3) 
xs = scale(x, center = TRUE, scale = TRUE) 

x.orig = t(apply(xs, 1, function(r)r*attr(xs,'scaled:scale') + attr(xs, 'scaled:center'))) 

print(x) 
    [,1] [,2] [,3] 
[1,] 4 2 3 
[2,] 5 7 1 
[3,] 6 10 11 
[4,] 9 12 8 

print(x.orig) 
    [,1] [,2] [,3] 
[1,] 4 2 3 
[2,] 5 7 1 
[3,] 6 10 11 
[4,] 9 12 8 

tener cuidado al usar funciones como identical():

print(x - x.orig) 
    [,1] [,2]   [,3] 
[1,] 0 0 0.000000e+00 
[2,] 0 0 8.881784e-16 
[3,] 0 0 0.000000e+00 
[4,] 0 0 0.000000e+00 

identical(x, x.orig) 
# FALSE 
+1

Gracias! Esto me ayudó a calcular los clústeres * centros * después de agrupar kMeans con una matriz escalada. 'centres <- t (aplicar (agrupamiento $ centros, 1, función (r) r * attr (escala_tamaño, 'escalado: escala') + attr (escala_tamaño, 'escala: centro')))' La respuesta aceptada no . – kadrian

+0

Estoy en su misma tarea exacta @kadrian, pero ¿por qué esta función no funciona en mis datos escalados? – Seymour

4

me sentí como este debería ser una función adecuada, aquí fue mi intento de que:

#' Reverse a scale 
#' 
#' Computes x = sz+c, which is the inverse of z = (x - c)/s 
#' provided by the \code{scale} function. 
#' 
#' @param z a numeric matrix(like) object 
#' @param center either NULL or a numeric vector of length equal to the number of columns of z 
#' @param scale either NULL or a a numeric vector of length equal to the number of columns of z 
#' 
#' @seealso \code{\link{scale}} 
#' mtcs <- scale(mtcars) 
#' 
#' all.equal(
#' unscale(mtcs), 
#' as.matrix(mtcars), 
#' check.attributes=FALSE 
#' ) 
#' 
#' @export 
unscale <- function(z, center = attr(z, "scaled:center"), scale = attr(z, "scaled:scale")) { 
    if(!is.null(scale)) z <- sweep(z, 2, scale, `*`) 
    if(!is.null(center)) z <- sweep(z, 2, center, `+`) 
    structure(z, 
    "scaled:center" = NULL, 
    "scaled:scale" = NULL, 
    "unscaled:center" = center, 
    "unscaled:scale" = scale 
) 
} 
+0

Y por diversión, he agregado esto a la versión de github del paquete 'stackoverflow'. –

Cuestiones relacionadas