rnormalize

How to normalize single vectors or vectors in a list?


I am trying to use lapply to apply this function to a vector but it just returns NaN.

normalize <- function(object) {
  return((object - min(object))/(max(object) - min(object)))
} 


x <- c(1, 5, 10)
lapply(x, normalize)
[[1]]
[1] NaN

[[2]]
[1] NaN

[[3]]
[1] NaN

It works fine when I use normalize(c(1, 5, 10)).


Solution

  • You obtain the correct result if you use normalize(x). In that case the function receives a vector with several numbers as argument, from which a minimum and maximum value can be determined to calculate normalized values.

    In contrast, with lapply(x,normalize) you effectively perform a loop which applies the function normalize() to every single element of the vector x. Since only one number (vector element) is passed to the function per iteration, in each case min(x) is equal to max(x). Therefore the denominator max(object)-min(object) is zero at each iteration, and the division by zero yields NaN each time the function is called.

    Edit

    The call with lapply could be very useful in the case where x is a list of vectors. Then one can obtain the normalized version (according to the function defined in the OP) of every vector in the list x at once.

    Here's an example:

    x <- list()
    x[[1]] <- c(1,3,9)
    x[[2]] <- c(2,4,4,8)
    x[[3]] <- c(1,2,3,5,8,13)
    > lapply(x,normalize)
    #[[1]]
    #[1] 0.00 0.25 1.00
    #
    #[[2]]
    #[1] 0.0000000 0.3333333 0.3333333 1.0000000
    #
    #[[3]]
    #[1] 0.00000000 0.08333333 0.16666667 0.33333333 0.58333333 1.00000000