【问题标题】:How can I calculate a mid-interval percentile rank in R without using a loop?如何在不使用循环的情况下计算 R 中的中间区间百分位等级?
【发布时间】:2014-09-02 18:48:55
【问题描述】:

我有一组不同组的数据——在这个例子中,我们只说两个组——我想计算一个中间区间百分位数排名,但我想使用dplyr(所以没有循环)。

以下是数据以及我目前拥有的数据:

library(dplyr);
group<-c("A","A","A","A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","B","B","B")
score<-c(1,2,3,4,5,6,7,8,9,10,10,9,10,7,8,4,5,10,11,12,13,10)
my_orig_df<-data.frame(group,score)
mydf<-my_orig_df %.%
  group_by(group) %.%
  mutate (   Cum= round( cume_dist(score),2) , myPTILE=percent_rank(score)) 
mydf

明确地说,我希望组 A 的第一个值是 0.05,而不是 0.09 或 0。 虽然结果很接近,但并不完全符合我的预期。

我可以通过嵌套循环获得想要的结果(但这不是我想要的):

 Ugroup<-unique (group)
for (i in 1:length(Ugroup)) {
  temp<-subset(mydf,group==Ugroup[i]) 
  for(j in 1:length(temp$score)) {
    ptile<-c(ptile,    ((sum(temp$score==temp$score[j])/2)+sum(temp$score<temp$score[j]))   /length(temp$score))
  } }

当我使用包含多个组的大型数据集的循环(上图)运行代码时,时间成为问题。

我尝试了以下方法:row_number(score); ntile(score, 99); min_rank(score); dense_rank(score); percent_rank(score); cume_dist(score),但没有一个结果是我想要的。任何想法将不胜感激。

【问题讨论】:

  • 抱歉 - 我正在显示我的新手状态,但是当我尝试处理 NA 值时,上面的公式会中断!我似乎得到一个字符串 ratehr 而不是一个向量。如果我稍微更改数据: group

标签: r dplyr percentile


【解决方案1】:

这似乎产生了与你的循环相同的东西。虽然不使用dplyr...

f <- function(z) sapply(z,function(x) (sum(z==x)/2+sum(z<x))/length(z))
ptile <- as.vector(t(aggregate(score~group,my_orig_df,f)[,-1]))
ptile
#  [1] 0.04545455 0.13636364 0.22727273 0.31818182 0.40909091 0.50000000 0.59090909
#  [8] 0.68181818 0.77272727 0.90909091 0.90909091 0.40909091 0.59090909 0.22727273
# [15] 0.31818182 0.04545455 0.13636364 0.59090909 0.77272727 0.86363636 0.95454545
# [22] 0.59090909

这是一个可能更快的 data.table 解决方案。

library(data.table)
DT <- as.data.table(my_orig_df)
ptile.dt <- DT[,sapply(score,function(x)(sum(score==x)/2+sum(score<x))/.N),by=group]$V1

identical(ptile,ptile.dt)
# [1] TRUE

【讨论】:

  • 谢谢。两个漂亮的解决方案!两者都会为我提供大量的工作来解决(我有点新手)。我希望在对 dplyr 的调用中运行它,因为这是我正在尝试的许多事情之一。虽然 dplyr 确实有一个 do() 命令,但我看不到如何使用 do() 来使用当前函数。还有其他建议吗?
猜你喜欢
  • 1970-01-01
  • 2015-01-24
  • 2013-04-14
  • 1970-01-01
  • 1970-01-01
  • 2012-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多