# Changing the scale of a variable to 0-100

I have constructed a social capital index using PCA technique. This index comprises values both positive and negative. I want to transform / convert this index to 0-100 scale to make it easy to interpret. Please suggest me an easiest way to do so.

• Related question: Standard formula for quick calculation of scores. – chl Apr 5 '12 at 16:52
• The logistic function used in logit models might come in handy as well. Depends on specific purpose. – Ondrej Apr 5 '12 at 17:45
• Scaling existing data to 0-100 has hidden risks when it will be applied to future (or additional) data. See consumerreports.org/cro/cars/…, for instance, where Consumer Reports wrote "...we faced a quandary: The Tesla initially scored 103 in the Consumer Reports' Ratings system, which by definition doesn’t go past 100. The car set a new benchmark, so we had to make changes to our scoring to account for it." – whuber Aug 15 '16 at 22:57

Any variable (univariate distribution) $v$ with observed $min_{old}$ and $max_{old}$ values (or these could be preset potential bounds for values) can be rescaled to range $min_{new}$ to $max_{new}$ by the following formula:

$\frac{max_{new}-min_{new}}{max_{old}-min_{old}}\cdot (v-max_{old})+max_{new}$

or

$\frac{max_{new}-min_{new}}{max_{old}-min_{old}}\cdot (v-min_{old})+min_{new}$.

For R there is also already available rescale function from scales package, which does exactly what you want and what @AndrewTulloch and @ttnphns described:

library(scales)
rescale(c(-10, -9, -5, 2, 6), to = c(0, 100)) ## Use scales:::rescale() if you have several packages loaded using the same function name
[1]   0.00   6.25  31.25  75.00 100.00


first, lets get some example data:

x <- runif(20, -10, 10)


Here are two functions that will work in R

rescale <- function(x) (x-min(x))/(max(x) - min(x)) * 100
rescale(x)


Or, you could use other transformations. For example, the logit transform was mentioned by @ondrej

plogis(x)*100


or, other transforms:

pnorm(x)*100
pnorm(x, 0, 100) * 100
punif(x, min(x), max(x))*100


Just to add to ttnphnss's answer, to implement this process in Python (for example), this function will do the trick:

from __future__ import division

def rescale(values, new_min = 0, new_max = 100):
output = []
old_min, old_max = min(values), max(values)

for v in values:
new_v = (new_max - new_min) / (old_max - old_min) * (v - old_min) + new_min
output.append(new_v)

return output

print rescale([1, 2, 3, 4, 5])
# [0.0, 25.0, 50.0, 75.0, 100.0]

• Thanks, does this formula also apply on negative values?? for example, if my original variable ranges from -10 to 10 . – Sohail Akram Apr 5 '12 at 20:34
• Yes - it works for all values - for example, print rescale([-10, -9, -5, 2, 6]) # [0.0, 6.25, 31.25, 75.0, 100.0] – Andrew Tulloch Apr 6 '12 at 5:13

I suggest not to bind the index to 0-100 interval, as it does not improve interpretation, but rather makes it more difficult. If the index constituents can be negative, then it is possible that the index becomes negative, and it reflects what's going on with constituents better than some low value in 0-100 range, in my opinion.

For R with standard packages loaded, you may just use scale() from 'base' package:

x=c(2,4,8,16)
x.scaled = scale(x,FALSE,max(x))  # divide each value in x by max(x)
x.scaled = as.vector(x.scaled)


use 'as.vector()' to retrieve the scaled x as vector.

• Since the original values can be negative, dividing by the largest value won't be sufficient. Please consider the question more carefully, and --- given David and Mikko have already posted answers that take that aspect into account -- to get thumbs to go up, you'd generally need to contribute something their answers did not. – Glen_b Aug 19 '15 at 0:18
• You are absolutely right, sorry for that. – user161922 Aug 19 '15 at 6:28