Solved – Transform data to have specific mean, minimum and maximum

I have found this in regards to transforming to specific mean and maximum, but I need to specify a minimum as well. Is there a way to do so?

I believe it will be a more complicated solution similar to what's proposed here, but I haven't found in this second link a solution to what I need.

Thanks in advance!

There are many different transformations that could work for this (probably infinite), but here is a fairly simple one that works for the median instead of the mean (thanks @Glen_b for catching the mistake):

  1. Subtract the current median from all data points (now the median will be 0).
  2. Divide all the positive values by the current max, then multiply them by the difference between the desired max and the desired median.
  3. Divide all the negative values by the absolute value of the current min, then multiply them by the difference between the desired median and the desired min.
  4. Add the desired median to all points.

Now the data will have the desired min, max, and median.

If the ratio of the differences between the extremes and the mean and the desired extremes are close then this will be close as well, otherwise some additional shifting will be needed.

Another approach for the mean (that keeps the order of the points):

  1. Subtract the minimum value from all values and divide all the new values by the new max (now the values will all be between 0 and 1).
  2. Raise all the values to the same power ($x^p$), finding the correct value of $p$ will be the tricky part, but you could use trial and error or an optimization or root finding function.
  3. Multiply by the difference between the desired max and min, then add the min.

The dataset will need to have at least 3 unique values for this (or anything that retains the order) to work.

Edit

Here is some example R code that uses the second option (tested this time to make sure that it works):

scaleMMM <- function(x, min.target=-1, max.target=1, mean.target=0,                      p.range=c(0.01,10)) {   tmpfun <- function(p) {     x2 <- x-min(x)     x2 <- x2/max(x2)     x2 <- x2^p     x2 <- x2*(max.target-min.target) + min.target     x2   }    p <- uniroot(function(p){mean(tmpfun(p))-mean.target}, p.range)$root    out <- tmpfun(p)   attr(out, 'p') <- p   out }   x1 <- rexp(25) summary(x1) x2 <- scaleMMM(x1) summary(x2)  plot(x1,x2) 

Similar Posts:

Rate this post

Leave a Comment