R - 排名和小组

时间:2015-08-03 11:16:45

标签: r dataframe rank calculated-columns

这将是一个很长的镜头,但无论如何我都会尝试。我想基于data.frame建立一个百分位(100组)或十分位数(10组)。 在这个例子中,我有一个包含891条记录的数据框。在这个data.frame中,我有以下变量。

  • Unique_ID(数字)。即唯一会员编号
  • xbeta(数字)鉴于信用评分。 (允许进行排名)
  • 好(数字)。二进制标志(0或1)。成员拖欠的指标
  • 糟糕(数字)。二进制标志(0或1)反向良好

我需要你的帮助才能在下面建立一个等效的表格。通过更改组的数量,我可以使用xbeta将其拆分为10或100。顶行是总数(可通过TYPE识别),我想制作下表(详见下表)

  • r_xbeta只是基于组数的行号。
  • 用于识别总排名或小组排名的类型
  • n =总计数
  • 好的数量|排名不好的旗帜
  • xbeta stats,min |最大|意思是中值
  • GB_Odds =等级为GOOD / BAD
  • LN_GB_ODDs =日志(GB_Odds)
  • 休息应该是自我解释

非常感谢您的帮助。 吉姆学习R

r_xbeta _TYPE_  n   GOOD    BAD xbeta_min   xbeta_max   xbeta_mean  xbeta_MEDIAN    GB_ODDS LN_GB_ODDS  Cummu_Good  Cummu_Bad   Cummu_Good_pct  Cummu_Bad_pct
.       0       891 342     549 -4.42       3.63        -0.7        -1.09           0.62295 -0.47329    342         549         100%            100%
0       1       89  4       85  -4.42       -2.7        -3.6        -3.57           0.04706 -3.05636    4           85          1.20%           15%
1       1       89  12      77  -2.69       -2.37       -2.55       -2.54           0.15584 -1.8589     16          162         4.70%           30%
2       1       87  12      75  -2.35       -1.95       -2.16       -2.2            0.16    -1.83258    28          237         8.20%           43%
3       1       93  14      79  -1.95       -1.54       -1.75       -1.79           0.17722 -1.73039    42          316         12%             58%
4       1       88  10      78  -1.53       -1.09       -1.33       -1.33           0.12821 -2.05412    52          394         15%             72%
5       1       89  27      62  -1.03       -0.25       -0.67       -0.69           0.43548 -0.8313     79          456         23%             83%
6       1       89  44      45  -0.24       0.33        0.05        0.03            0.97778 -0.02247    123         501         36%             91%
7       1       89  54      35  0.37        1.07        0.66        0.63            1.54286 0.43364     177         536         52%             98%
8       1       88  77      11  1.08        2.15        1.56        1.5             7       1.94591     254         547         74%             100%
9       1       90  88      2   2.18        3.63        2.77        2.76            44      3.78419     342         549         100%            100%

2 个答案:

答案 0 :(得分:0)

A reproducible example会很棒,即我们可以复制粘贴到我们的终端,以证明您的问题。例如,以下是我将使用的数据框:

set.seed(1) # so you get the same random numbers as me
my_dataframe <- data.frame(Unique_ID = 1:891,
                           xbeta=rnorm(891, sd=10),
                           Good=round(runif(891) < 0.5),
                           Bad=round(runif(891) < 0.5))
head(my_dataframe)
#   Unique_ID     xbeta Good Bad
# 1         1 -6.264538    1   0
# 2         2  1.836433    1   0
# 3         3 -8.356286    0   1
# 4         4 15.952808    1   1
# 5         5  3.295078    1   0
# 6         6 -8.204684    1   1

(具体数字与你的问题无关,这就是我编写随机数字的原因)。

这个想法是:

  • 计算每行所属的分位数:见?quantile。你可以指定你想要的分位数(我已经显示了十分位数)

    quantile(my_dataframe$xbeta, seq(0, 1, by=.1))
    #          0%         10%         20%         30%         40%         50%         60%         70%         80%         90%        100% 
    # -30.0804860 -13.3880074  -8.7326454  -5.1121923  -3.0097613  -0.4493361   2.3680366   5.3732613   8.7867326  13.2425863  38.1027668 
    

    这给出了分位数截止值;如果你在这些上使用cut,你可以添加一个变量来说明每行的分位数(?cut):

    my_dataframe$quantile <- cut(my_dataframe$xbeta,
                                 quantile(my_dataframe$xbeta, seq(0, 1, by=.1)))
    

    看一下head(my_dataframe)看看这是做什么的。 quantile列是一个因素。

  • 按分位数分割您的数据框,并计算每个数据的统计数据。您可以使用plyrdplyrdata.table个包;我推荐前两个中的一个,因为你是R的新手。如果你需要在有效(数千行)的大表上进行大量合并和计算,请使用data.table,但学习曲线要​​陡峭得多。我会告诉你plyr纯粹是因为它是我觉得最容易的。 dplyr非常相似,但语法不同。

    # The idea: `ddply(my_dataframe, .(quantile), FUNCTION)` applies FUNCTION
    #  to each subset of `my_dataframe`, where we split it up into unique
    # `quantile`s.
    # For us, `FUNCTION` is `summarize`, which calculates summary stats
    #  on each subset of the dataframe.
    # The arguments after `summarize` are the new summary columns we
    #  wish to calculate.
    
    library(plyr)
    output = ddply(my_dataframe, .(quantile), summarize,
                   n=length(Unique_ID), GOOD=sum(Good), BAD=sum(Bad),
                   xbeta_min=min(xbeta), xbeta_max=max(xbeta),
                   GB_ODDS=GOOD/BAD) # you can calculate the rest yourself,
                                     # "the rest should be self explanatory".
    > head(output, 3)
           quantile  n GOOD BAD  xbeta_min  xbeta_max   GB_ODDS
     1 (-30.1,-13.4] 89   41  39 -29.397737 -13.388007 1.0512821
     2 (-13.4,-8.73] 89   49  45 -13.353714  -8.732645 1.0888889
     3 (-8.73,-5.11] 89   46  48  -8.667335  -5.112192 0.9583333
    
  • 计算其他列。有关累计金额,请参阅(例如)?cumsum。例如output$cummu_good <- cumsum(output$GOOD)
  • 添加“总计”行。你应该能够做到这一点。您可以使用outputrbind添加额外的行。

答案 1 :(得分:0)

这是我的脚本的最终版本,带有数学咖啡的指导。我不得不使用.bincode而不是建议的剪切,因为“'break'不是唯一的”错误。

谢谢大家。

set.seed(1) # so you get the same random numbers as me
my_dataframe <- data.frame(Unique_ID = 1:891,
                           xbeta=rnorm(891, sd=10),
                           Good=round(runif(891) < 0.5),
                           Bad=round(runif(891) < 0.5))
head(my_dataframe)
quantile(my_dataframe$xbeta, seq(0, 1, by=.1))
my_dataframe$quantile = .bincode(my_dataframe$xbeta,quantile(my_dataframe$xbeta,seq(0,1,by=.1)))
library(plyr)
output = ddply(my_dataframe, .(quantile), summarize,
               n=length(Unique_ID), GOOD=sum(Good), BAD=sum(Bad),
               xbeta_min=min(xbeta), xbeta_max=max(xbeta), xbeta_median=median(xbeta), xbeta_mean=mean(xbeta),
               GB_ODDS=GOOD/BAD, LN_GB_ODDS = log(GOOD/BAD))
output$cummu_good = cumsum(output$GOOD)
output$cummu_bad = cumsum(output$BAD)
output$cummu_n = cumsum(output$n)
output$sum_good = sum(output$GOOD)
output$sum_bad = sum(output$BAD)
output$cummu_good_pct = cumsum(output$GOOD/output$sum_good)
output$cummu_bad_pct = cumsum(output$BAD/output$sum_bad)
output[["sum_good"]]=NULL
output[["sum_bad"]]=NULL
output