将一系列值转换为相对1-10的比例

时间:2012-02-16 02:05:56

标签: scale average

假设我有几组这样的值:

高度(以英寸为单位):

John 72.3
Peter 64.5
Frank 78.5
Susan 65.8
Judy 69.0
Mary 72.7

体重(磅):

John 212
Peter 232
Frank 140
Susan 355
Judy 105
Mary 76

年龄(自出生后的秒数)

John 662256000
Peter 1292976000
Frank 977616000
Susan 1229904000
Judy 599184000
Mary 283824000

将这些值相对于其他值转换为1-10比例的最佳方法是什么?

我希望能够说John的身高是6/10,身高是10/10,而年龄是3/10(制造价值)。

我希望能够避免的一个问题是,任何一方的极端值都会使系统过度扭曲。一个非常沉重或高大的人不应该扭曲整个规模。

4 个答案:

答案 0 :(得分:1)

在R

heightOrder <- order(height)

将为您提供每个项目的排名顺序。如果有10则将从1-10开始。您可以将其缩放到10。

heightOrder <- heightOrder / max(heightOrder) * 10

现在从0-10开始。虽然,现在我看你的问题,你问了&#34;最好的方式&#34;。缩放的最佳方式取决于您想要完成的任务。您需要在问题中添加更多内容才能真正了解最佳方式。

答案 1 :(得分:1)

不是简单的:

y = (x-min)/(max-min)*9+1

也许使用

进行一些舍入
sprintf '%.0f'

use strict;
use warnings;

use List::MoreUtils qw( minmax );

my %people = (
   John  => { height => 72.3, weight => 212, age =>  662256000 },
   Peter => { height => 64.5, weight => 232, age => 1292976000 },
   Frank => { height => 78.5, weight => 140, age =>  977616000 },
   Susan => { height => 65.8, weight => 355, age => 1229904000 },
   Judy  => { height => 69.0, weight => 105, age =>  599184000 },
   Mary  => { height => 72.7, weight =>  76, age =>  283824000 },
);

sub scale {
   my ($min, $max, $x) = @_;
   return ($x-$min)/($max-$min)*9+1;
}

my ($min_height, $max_height) = minmax( map $_->{height}, values %people );
my ($min_weight, $max_weight) = minmax( map $_->{weight}, values %people );
my ($min_age,    $max_age   ) = minmax( map $_->{age   }, values %people );

for my $name (keys %people) {
   my $person = $people{$name};
   printf("%-6s  height: %2.0f/10  weight: %2.0f/10  age: %2.0f/10\n",
      "$name:",
      scale($min_height, $max_height, $person->{height}),
      scale($min_weight, $max_weight, $person->{weight}),
      scale($min_age,    $max_age,    $person->{age   }),
   );
}

输出:

Susan:  height:  2/10  weight: 10/10  age:  9/10
John:   height:  6/10  weight:  5/10  age:  4/10
Mary:   height:  6/10  weight:  1/10  age:  1/10
Judy:   height:  4/10  weight:  2/10  age:  4/10
Peter:  height:  1/10  weight:  6/10  age: 10/10
Frank:  height: 10/10  weight:  3/10  age:  7/10

答案 2 :(得分:1)

如果您希望样品在1,2,... 10中均匀分布,那么我建议您使用分位数。在R:

> relative.scale <- function(x) {
+     percentiles <- quantile(x, probs = seq(0,0.9,0.1))
+     sapply(x, function(v)sum(percentiles <= v))
+ }

> x <- runif(100)
> s <- relative.scale(x)
> table(s)
s
 1  2  3  4  5  6  7  8  9 10 
10 10 10 10 10 10 10 10 10 10 

答案 3 :(得分:1)

在R中,您可以使用quantile查找数据的十分位数,然后使用findInterval查找每个观察所在的时间间隔。

x <- rnorm(100)
findInterval( x, quantile(x, seq(0,1,length=11))) )