2016-06-07 3 views
0

У меня есть большой r data.frame с около 500 столбцами. Я хочу добавить существующую функцию масштабирования, а также попробовать различную функцию нормализации в графе по разумным правилам.R: Применение функции нормализации column wise - large DataFrame/DataTable

В существующей шкалы функции

library(dplyr) 

set.seed(1234) 
dat <- data.frame(x = rnorm(10, 30, .2), 
        y = runif(10, 3, 5), 
        z = runif(10, 10, 20), k = runif(10, 5, 10)) 

dat %>% mutate_each_(funs(scale),vars=c("y","z")) 

Question1: В этом случае переменными являются только два, но если у вас есть 500 столбцов нормализуется Что лучше? Я попробовал следующее:

dnot <- c("y", "z") 
dat %>% mutate_each_(funs(scale),vars=!(names(dat) %in% dnot)) 

Ошибка:

Error in UseMethod("as.lazy_dots") : 
    no applicable method for 'as.lazy_dots' applied to an object of class "logical" 

Вопрос2: Вместо того, чтобы использовать встроенную функцию масштаба, я хочу, чтобы применить свою собственную функцию для нормализации кадра данных.

пример: я следующая функция

normalized_columns <- function(x) 
{ 
    r <- (x/sum(x)) 
} 

Вопрос2: Как я могу эффективно применить это ко всем столбцам, оставив только 3 или 4 колонки.

ответ

1

Есть лучше подходит, но я обычно делаю что-то вроде:

set.seed(1234) 
x = rnorm(10, 30, .2) 
y = runif(10, 3, 5) 
z = runif(10, 10, 20) 
k = runif(10, 5, 10) 
a = rnorm(10, 30, .2) 
b = runif(10, 3, 5) 
c = runif(10, 10, 20) 
d = runif(10, 5, 10) 

normalized_columns <- function(x) 
{ 
x/sum(x) 
} 

dat<-data.frame(x,y,z,k,a,b,c,d) 
dat[,c(1,4,6:8)]<-sapply(dat[,c(1,4,6:8)], normalized_columns) 

Edit: с точки зрения эффективности идет, это довольно быстро:

set.seed(100) 
dat<-data.frame(matrix(rnorm(50000, 5, 2), nrow = 100, ncol = 500)) 
cols<-sample.int(500, 495, replace = F) 
system.time(dat[,cols]<-sapply(dat[,cols], normalized_columns)) 
##user system elapsed 
##0.03 0.00 0.03 
1

Как OP используется dplyr методы, один вариант будет использовать setdiff с mutate_each_

dat %>% 
    mutate_each_(funs(scale), setdiff(names(dat), dnot)) 
#    x  y  z   k 
#1 -0.8273937 3.633225 14.56091 0.22934964 
#2 0.6633811 3.605387 12.65187 0.76742806 
#3 1.4738069 3.318092 13.04672 -1.16688369 
#4 -1.9708424 3.079992 15.07307 0.62528427 
#5 0.8157183 3.437599 11.81096 -1.06313355 
#6 0.8929749 4.621197 17.59671 -0.06743894 
#7 -0.1923930 4.051395 12.01248 0.94484655 
#8 -0.1641660 4.829316 12.58810 -0.16575678 
#9 -0.1820615 4.662690 19.92150 -1.55940662 
#10 -0.5090247 3.091541 18.07352 1.45571106 

Или подмножество names на основе логического индекса

dat %>% 
    mutate_each_(funs(scale), names(dat)[!names(dat) %in% dnot]) 
#   x  y  z   k 
#1 -0.8273937 3.633225 14.56091 0.22934964 
#2 0.6633811 3.605387 12.65187 0.76742806 
#3 1.4738069 3.318092 13.04672 -1.16688369 
#4 -1.9708424 3.079992 15.07307 0.62528427 
#5 0.8157183 3.437599 11.81096 -1.06313355 
#6 0.8929749 4.621197 17.59671 -0.06743894 
#7 -0.1923930 4.051395 12.01248 0.94484655 
#8 -0.1641660 4.829316 12.58810 -0.16575678 
#9 -0.1820615 4.662690 19.92150 -1.55940662 
#10 -0.5090247 3.091541 18.07352 1.45571106 

Если мы используем mutate_each, другой вариант one_of

dat %>% 
    mutate_each(funs(scale), -one_of(dnot)) 
#   x  y  z   k 
#1 -0.8273937 3.633225 14.56091 0.22934964 
#2 0.6633811 3.605387 12.65187 0.76742806 
#3 1.4738069 3.318092 13.04672 -1.16688369 
#4 -1.9708424 3.079992 15.07307 0.62528427 
#5 0.8157183 3.437599 11.81096 -1.06313355 
#6 0.8929749 4.621197 17.59671 -0.06743894 
#7 -0.1923930 4.051395 12.01248 0.94484655 
#8 -0.1641660 4.829316 12.58810 -0.16575678 
#9 -0.1820615 4.662690 19.92150 -1.55940662 
#10 -0.5090247 3.091541 18.07352 1.45571106 

setdiff вариант с data.table будет

library(data.table) 
nm1 <- setdiff(names(dat), dnot) 
setDT(dat)[, (nm1) := lapply(.SD, scale), .SDcols = nm1] 
Смежные вопросы