Search code examples
rscale

R Scale a vector with negative and positive numbers between 1 and -1


I have a vector as follows

vec <- c(0, -0.072, -0.092, -0.092, -0.222, -0.445, -0.345, -0.031, 
0.016, 0.158, 0.349, 0.749, 1.182, 1.289, 1.578, 1.767, 1.621, 
1.666, 1.892, 1.866, 1.821, 1.702, 1.69, 1.53, 1.38, 1.494, 1.833, 
2.392, 2.502, 2.921, 3.363, 3.698, 3.645, 3.89, 3.987, 4.066, 
3.963, 3.749, 3.512, 3.259, 3.153, 2.972, 2.918, 2.93, 2.719, 
2.458, 2.275, 2.346, 2.588, 2.774, 2.607, 2.336, 1.799, 1.365, 
1.025, 0.379, -0.087, -0.765, -1.19, -1.423, -1.751, -1.965, 
-1.907, -1.919, -1.848, -1.772, -1.49, -1.19, -1.104, -1.138, 
-1.054, -1.139, -1.269, -1.429, -1.56, -1.543, -1.364, -1.318, 
-1.094, -1.061, -0.918, -0.861, -0.913, -0.767, -0.615, -0.532, 
-0.615, -0.688, -0.75, -0.724, -0.755, -0.685, -0.752, -0.863, 
-0.944, -1.004, -1.02, -1.041, -1.073, -1.392)

The following code scales this vector between 1 and -1 perfectly fine.

scale <- function(input)
{
  min_val = min(input, na.rm = T)
  max_val = max(input, na.rm = T)
  
  average = (min_val + max_val) / 2
  range = (max_val - min_val) / 2
  normalized_x = (input - average) / range
  return(normalized_x)
}

However, I want to scale this vector from -1 to 1 while keeping the midpoint at 0.

Can someone please improve the above function to center this scaling around 0?

Thanks!


Solution

  • Calling this operation "normalization" is rather confusing. The correct term is scaling. Normalization means you have transformed the values to something resembling a Normal distribution. (There is an R function named scale,)

    This will scale the values below 0 to the range [-1, 0) and the values above 0 to the range (0,1] which is what I understand to be the desire:

    c( -vec[vec<0]/min(vec), vec[vec>=0]/max(vec) )
    

    They are not in the original order, however. If that is desired, you might need to put an ifelse operation in place:

     newvec <- ifelse(vec < 0 , -vec[vec<0]/min(vec), vec[vec>=0]/max(vec)  )
      #-------------
     > sum(newvec<0)
    [1] 51
    > sum(newvec>0)
    [1] 47
    > sum(newvec==0)
    [1] 2
    

    enter image description here