【问题标题】:Calculating quintile based scores on R在 R 上计算基于五分位数的分数
【发布时间】:2016-09-26 02:39:29
【问题描述】:

我有一个数据框,其中包含年份(2006 年至 2010 年)、4 个行业部门、150 个公司名称以及这些公司的净收入。我总共有 750 个观察结果,每个公司每年都有一个观察结果。我想根据五分位数为公司在每个行业年度内的收入打分。因此,每个行业年度内收入位于前 20% 的公司得分为 5,接下来的 20% 得分为 4,依此类推。最低的 20% 得 1 分。

示例数据库为:

Year Industry Firm Income
2006 Chemicals ABC 334.50
2007 Chemicals ABC 388.98
.
.
2006 Pharma XYZ 91.45
.
.

我如何在 R 中做到这一点?我已经尝试过aggregatetapply 以及quantile,但无法得出应该用于此的逻辑。请帮忙。

我尝试这样做只是为了将 1 分分配给最低的 20%,但它返回了错误。

db10$score <- ifelse(db10$income < aggregate(income~Year+industry,db10,quantile,c(0.2)),1,0)

【问题讨论】:

  • 你能提供一个你的数据集的例子吗?
  • 发布了一个典型的数据集样本

标签: r statistics aggregate-functions quantile tapply


【解决方案1】:

试试这个方法:

首先,我将创建用于测试以下功能的示例:

y = c(rep(2001,15),rep(2002,15),rep(2003,15))
ind = c("A","B","C","D","E","G","H","I","J","K","L","M","N","O","P")
val = runif(45,10,100)
df = data.frame(y,ind,val)

head(df,20)

      y ind      val
1  2001   A 63.32011
2  2001   B 85.67976
3  2001   C 86.77527
4  2001   D 32.18319
5  2001   E 49.86626
6  2001   G 57.73214
7  2001   H 18.08216
8  2001   I 22.31012
9  2001   J 44.11174
10 2001   K 54.76902
11 2001   L 41.82495
12 2001   M 64.84514
13 2001   N 59.16529
14 2001   O 61.28870
15 2001   P 84.76561
16 2002   A 83.68185
17 2002   B 45.01354
18 2002   C 62.22964
19 2002   D 98.41717
20 2002   E 19.91548

有 3 年,行业从 A 到 P。数据框按年份排序,以后按行业排序。

下面的这个函数采用年份值y 并计算所有df$val 的五分位数类别,其中年份df$yy

quintile = function(y) {
    x = df$val[df$y == y]
    qn = quantile(x, probs = (0:5)/5)
    result = as.numeric(cut(x, qn, include.lowest = T))
}

唯一剩下的就是将此函数应用于唯一的年份值

df$qn = unlist(lapply(unique(df$y), quintile))

结果:

> head(df,20)
      y ind      val qn
1  2001   A 63.32011  4
2  2001   B 85.67976  5
3  2001   C 86.77527  5
4  2001   D 32.18319  1
5  2001   E 49.86626  2
6  2001   G 57.73214  3
7  2001   H 18.08216  1
8  2001   I 22.31012  1
9  2001   J 44.11174  2
10 2001   K 54.76902  3
11 2001   L 41.82495  2
12 2001   M 64.84514  4
13 2001   N 59.16529  3
14 2001   O 61.28870  4
15 2001   P 84.76561  5
16 2002   A 83.68185  4
17 2002   B 45.01354  1
18 2002   C 62.22964  3
19 2002   D 98.41717  5
20 2002   E 19.91548  1

也许有一个更简单的方法来实现这个......

按两列分组

如果要根据两列的分组计算五分位数:ygrp

y = c(rep(2001,15),rep(2002,15),rep(2003,15))
grp = c("G1","G1","G1","G1","G1","G2","G2","G2","G2","G2","G3","G3","G3","G3","G3")
ind = c("A","B","C","D","E","G","H","I","J","K","L","M","N","O","P")
val = round(runif(45,10,100))
df = data.frame(y,grp,ind,val)

> head(df,20)
      y grp ind val
1  2001  G1   A  40
2  2001  G1   B  33
3  2001  G1   C  65
4  2001  G1   D  99
5  2001  G1   E  18
6  2001  G2   G  36
7  2001  G2   H  15
8  2001  G2   I  17
9  2001  G2   J  42
10 2001  G2   K  67
11 2001  G3   L  60
12 2001  G3   M  34
13 2001  G3   N  61
14 2001  G3   O  76
15 2001  G3   P  15
16 2002  G1   A  18
17 2002  G1   B  15
18 2002  G1   C  44
19 2002  G1   D  79
20 2002  G1   E  22

然后使用:

quintile = function(z) {
    x = df$val[df$y == z[1] & df$grp == z[2]]
    qn = quantile(x, probs = (0:5)/5)
    result = as.numeric(cut(x, qn, include.lowest = T))
}


df$qn = as.vector(apply(unique(df[,c("y","grp")]),1, quintile))

结果:

> head(df,20)
      y grp ind val qn
1  2001  G1   A  40  3
2  2001  G1   B  33  2
3  2001  G1   C  65  4
4  2001  G1   D  99  5
5  2001  G1   E  18  1
6  2001  G2   G  36  3
7  2001  G2   H  15  1
8  2001  G2   I  17  2
9  2001  G2   J  42  4
10 2001  G2   K  67  5
11 2001  G3   L  60  3
12 2001  G3   M  34  2
13 2001  G3   N  61  4
14 2001  G3   O  76  5
15 2001  G3   P  15  1
16 2002  G1   A  18  2
17 2002  G1   B  15  1
18 2002  G1   C  44  4
19 2002  G1   D  79  5
20 2002  G1   E  22  3

在这个例子中,y 是年份,grp 是行业组,ind 是公司,val 是收入。

注意apply里面c("y","grp")的顺序和五分位函数里面的列名。您必须将它们替换为您想要的列名。

请注意,如果您的团队规模较小(在此示例中,每组 5 家公司),五分位数可能不是唯一的,并且会弹出错误消息。

使用问题中的列名

quintile = function(z) {
    x = df$Income[df$Year == z[1] & df$Industry == z[2]]
    qn = quantile(x, probs = (0:5)/5)
    result = as.numeric(cut(x, qn, include.lowest = T))
}


df$qn = as.vector(apply(unique(df[,c("Year","Industry")]),1, quintile))

在应用此之前,数据框df 必须按年份和行业排序。

【讨论】:

  • @RSchifini 非常感谢,该代码适用于您的价值观。但。对不起,我想我没有说清楚。我希望在每个行业年度内应用五分位数分数。一年(比如 2001 年),行业 A 可能有许多公司(A1、A2、A3...)。评分需要在这些公司(A1、A2、A3...)内每年进行。
  • @Rschifini 我收到一条错误消息:Error in $(*tmp*, "qn", value = list(1` = c(3, 5, 5, : 替换有 30 行,数据有 2398` 我有 5 年的数据和 6 个组,这就是 30 的原因。我根据您的代码重命名了我的变量并运行它。
  • 您的数据是先按年份排序,然后按行业排序吗?我将为您的列名添加代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 2020-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-19
相关资源
最近更新 更多