Невозможно заставить работать функцию масштабирования диапазона - PullRequest
1 голос
/ 30 марта 2020

Я пытаюсь применить формулу масштабирования диапазона для столбцов набора данных. формула , которую я использую, является средней нормализацией доступных методов масштабирования диапазона.

formula

В настоящее время я пытался использовать следующий код:

rangescale <- function(r){
  colmean <- apply(r,2,mean)
  colsd <- apply(r, 2, sd)
  cv <- sweep(r, 2, colmean, "-")
  xmax <- apply(r, 2, max)
  xmin <- apply(r,2, min)
  ma.mi <- apply(xmax, 2, xmin, "-")
  rv <- sweep(cv, 2, ma.mi, "/")
  return(rv)
}

Это дает мне:

Error in get(as.character(FUN), mode = "function", envir = envir) : 
  object 'xmin' of mode 'function' was not found 

Не похоже, что у base r есть функция минимума, есть ли другие способы получить минимальное и максимальное количество столбцов? Или есть проблемы, которые я полностью упустил?

Ответы [ 2 ]

2 голосов
/ 30 марта 2020

Вы можете создать функцию для применения масштабирования

rangescale <- function(x) (x  - mean(x))/(max(x) - min(x))

и применять ее по столбцам

apply(r, 2, rangescale)

Или с помощью dplyr

library(dplyr)
r %>% summarise_all(rangescale)

Чтобы передать весь набор данных в функцию, мы можем взять apply внутри функции

rangescale <- function(r) {
  apply(r, 2, function(x) (x  - mean(x))/(max(x) - min(x)))
}

и затем вызвать его как:

r1 <- rangescale(r)
1 голос
/ 30 марта 2020

Это может не иметь большого значения в вашем текущем случае использования, но я оставлю это здесь для потомков:

Вы можете сделать это немного более эффективным, используя пакет matrixStats (полезно для больших матриц):

library(matrixStats)
library(microbenchmark)
set.seed(1)
n.col = 1000
n.row = 120
my.matrix <- matrix(rnorm(n.row * n.col), nrow = n.row)

rangescale1 <- function(x){
    cr <- colRanges(x)
    t((t(x) - colMeans(x))/(cr[,2] - cr[,1]))
}

rangescale2 <- function(r) {
    apply(r, 2, function(x) (x  - mean(x))/(max(x) - min(x)))
}

microbenchmark(
    rangescale1(my.matrix),
    rangescale2(my.matrix)
)
#> Unit: microseconds
#>                    expr      min        lq     mean    median        uq
#>  rangescale1(my.matrix)  823.150  854.3335 1135.847  900.5095  981.5745
#>  rangescale2(my.matrix) 5564.432 5787.9025 6717.374 5905.3510 6687.6110
#>        max neval cld
#>   5689.234   100  a 
#>  21350.869   100   b

all.equal(rangescale1(my.matrix), rangescale2(my.matrix))
#> [1] TRUE

Создано в 2020-03-30 пакетом Представить (v0.3.0)

...