Below is your code followed by a tidyverse implementation. Things like dplyr::select and dplry::mutate make a lot of common table operations easier. scale is not part of the tidyverse so there is some code to coerce its results into the tidyverse.
Also it would be helpful in the future if you used a reprex for your
code and showed the results that you got. Here is link to reprex help
http://reprex.tidyverse.org/articles/reprex.html
suppressPackageStartupMessages(library(tidyverse))
# your code followed by tidyverse implementation
# define dummy train and test sets
# make sequences repeatable so tidyverse code output can be compared
# some things are changed in your code to guarentee that same
# random sequences are used in the tidyverse example
set.seed(0)
n <- rnorm(10,1)
un <- runif(10)
train <- data.frame(letters = LETTERS[1:10],
months = month.abb[1:10], numbers = 1:10,
x = n, y = un)
test <- train
test$x <- rnorm(10, 1)
test$y <- runif(10)
# names of variables I don't want to scale
varnames <- c("letters", "months", "numbers")
# index vector of columns which must not be scaled
index <- names(train) %in% varnames
# scale only the columns not in index
temp <- scale(train[, !index])
train[, !index] <- temp
# get the means and standard deviations from temp, to scale test too
means <- attr(temp, "scaled:center")
standard_deviations <- attr(temp, "scaled:center")
# scale test
test[, !index] <- scale(test[, !index], center = means, scale = standard_deviations)
# tidyverse implementation
#
set.seed(0)
# make tibble not data.frame
n <- rnorm(10,1)
un <- runif(10)
train2 <- tibble(letters = LETTERS[1:10], months = month.abb[1:10], numbers = 1:10,
x = n, y = un)
n <- rnorm(10,1)
un <- runif(10)
# mutate train to make test2
test2 <- dplyr::mutate(train2, x = n, y = un)
# yank scale results into the tidyverse
# select used to drop columns
scaled <- scale(select(train2, -letters, -months, -numbers))
means2 <- attr(scaled, "scaled:center")
standard_deviations2 <- attr(scaled, "scaled:center")
scaled <- as_tibble(scaled)
# mutate trai2 with scaled results
train2 <- mutate(test2, x = scaled$x, y = scaled$y)
st <- as_tibble(scale(select(test2, -letters, -months, -numbers),
center = means2, scale = standard_deviations2))
# replace x and y with scaled results
test2 <- mutate(test2, x = st$x, y = st$y)
# test and tests two are not exactly the same
# structures so identical will not work
# one has attributes and the other does not
#
# check that both have the same values
purrr::map2_dbl(test2$x, test$x, ~ .x - .y)
#> [1] 0 0 0 0 0 0 0 0 0 0
purrr::map2_dbl(test2$y, test$y, ~ .x - .y)
#> [1] 0 0 0 0 0 0 0 0 0 0
str(test)
#> 'data.frame': 10 obs. of 5 variables:
#> $ letters: Factor w/ 10 levels "A","B","C","D",..: 1 2 3 4 5 6 7 8 9 10
#> $ months : Factor w/ 10 levels "Apr","Aug","Feb",..: 4 3 7 1 8 6 5 2 10 9
#> $ numbers: int 1 2 3 4 5 6 7 8 9 10
#> $ x : num -0.5669 -0.0785 -0.9205 0.0565 -1.1748 ...
#> $ y : num 0.4993 0.0337 0.864 -0.0518 -0.4702 ...
str(test2)
#> Classes 'tbl_df', 'tbl' and 'data.frame': 10 obs. of 5 variables:
#> $ letters: chr "A" "B" "C" "D" ...
#> $ months : chr "Jan" "Feb" "Mar" "Apr" ...
#> $ numbers: int 1 2 3 4 5 6 7 8 9 10
#> $ x : atomic -0.5669 -0.0785 -0.9205 0.0565 -1.1748 ...
#> ..- attr(*, "scaled:center")= Named num 1.359 0.462
#> .. ..- attr(*, "names")= chr "x" "y"
#> ..- attr(*, "scaled:scale")= Named num 1.359 0.462
#> .. ..- attr(*, "names")= chr "x" "y"
#> $ y : atomic 0.4993 0.0337 0.864 -0.0518 -0.4702 ...
#> ..- attr(*, "scaled:center")= Named num 1.359 0.462
#> .. ..- attr(*, "names")= chr "x" "y"
#> ..- attr(*, "scaled:scale")= Named num 1.359 0.462
#> .. ..- attr(*, "names")= chr "x" "y"