Search code examples
rscaletransform

DMwR::unscale to unscale only selected columns


I've got a data.frame with 4 columns which I want to scale and then add some new columns (without scaling them). Then I perform some calculations after which I need to unscale only first 4 columns (as the remaining two weren't scaled in the first place). DMwR::unscale seems to allow for that with col.ids argument. But when I specify the fucntion like below it returns

Error in DMwR::unscale(cbind(scale(x), x2), scale(x), 1:4) : Incorrect dimension of data to unscale.

x <- matrix(2*rnorm(400) + 1, ncol = 4)
x2 <- matrix(9*rnorm(200), ncol = 2)
DMwR::unscale(cbind(scale(x), x2), scale(x), 1:4)

What am I doing wrong? How can I unscale only selected 4 first columns of matrix?


Solution

  • The DMwR::unscale(vals, norm.data, col.ids) function requires that norm.data has a number of columns larger than that of vals.
    I suggest to consider the following modified version of unscale:

    myunscale <- function (vals, norm.data, col.ids)  {
        cols <- if (missing(col.ids)) 1:NCOL(vals) else col.ids
        if (length(cols) > NCOL(vals)) 
            stop("Incorrect dimension of data to unscale.")
        centers <- attr(norm.data, "scaled:center")[cols]
        scales <- attr(norm.data, "scaled:scale")[cols]
        unvals <- scale(vals[,cols], center = (-centers/scales), scale = 1/scales)
        unvals <- cbind(unvals,vals[,-cols])
        attr(unvals, "scaled:center") <- attr(unvals, "scaled:scale") <- NULL
        unvals
    }
    
    set.seed(1)
    x <- matrix(2*rnorm(4000) + 1, ncol = 4)
    x2 <- matrix(9*rnorm(2000), ncol = 2)
    x_unsc <- myunscale(cbind(scale(x), x2), scale(x) , 1:4)
    

    The mean values and the standard deviations of x_unsc are:

    apply(x_unsc, 2, mean)
    # [1]  0.9767037  0.9674762  1.0306181  1.0334445 -0.1805717 -0.1053083
    
    apply(x_unsc, 2, sd)
    # [1] 2.069832 2.079963 2.062214 2.077307 8.904343 8.810420