这将是一个很长的镜头,但无论如何我都会尝试。我想基于data.frame建立一个百分位(100组)或十分位数(10组)。 在这个例子中,我有一个包含891条记录的数据框。在这个data.frame中,我有以下变量。
我需要你的帮助才能在下面建立一个等效的表格。通过更改组的数量,我可以使用xbeta将其拆分为10或100。顶行是总数(可通过TYPE识别),我想制作下表(详见下表)
非常感谢您的帮助。 吉姆学习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%
答案 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
列是一个因素。
按分位数分割您的数据框,并计算每个数据的统计数据。您可以使用plyr
,dplyr
或data.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)
。output
向rbind
添加额外的行。答案 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