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.
-
1Related question: [Standard formula for quick calculation of scores](http://stats.stackexchange.com/q/20439/930). – chl Apr 05 '12 at 16:52
-
The [logistic function](http://en.wikipedia.org/wiki/Logit#Definition) used in logit models might come in handy as well. Depends on specific purpose. – Ondrej Apr 05 '12 at 17:45
-
2Scaling existing data to 0-100 has hidden risks when it will be applied to future (or additional) data. See http://www.consumerreports.org/cro/cars/tesla-model-s-p85d-earns-top-road-test-score, 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
6 Answers
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}$.

- 2,568
- 3
- 21
- 38

- 51,648
- 40
- 253
- 462
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

- 7,060
- 6
- 44
- 89
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]

- 164
- 1
- 4
-
Thanks, does this formula also apply on negative values?? for example, if my original variable ranges from -10 to 10 . – Sohail Akram Apr 05 '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 06 '12 at 05: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.

- 55,939
- 5
- 90
- 176
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.

- 119
- 2
-
4Since 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 00:18
-