使用分组变量计算值的95th百分位数

9
我正在尝试计算按流域分组的多个水质值的95百分位数,例如:
Watershed   WQ
50500101    62.370661
50500101    65.505046
50500101    58.741477
50500105    71.220034
50500105    57.917249

我看了这篇发布的问题 - 关于分组变量的每个观察值的百分位数。它似乎非常接近我想做的事情,但它是针对每个观察值的。我需要针对每个分组变量。所以理想情况下,

Watershed   WQ - 95th
50500101    x
50500105    y
5个回答

9

您可以使用plyr库来实现此功能。我们指定分组变量Watershed并要求计算WQ的95%分位数。

library(plyr)
#Random seed
set.seed(42)
#Sample data
dat <- data.frame(Watershed = sample(letters[1:2], 100, TRUE), WQ = rnorm(100))
#plyr call
ddply(dat, "Watershed", summarise, WQ95 = quantile(WQ, .95))

以及结果

  Watershed     WQ95
    1         a 1.353993
    2         b 1.461711

我会倾向于使用daply,因为结果可以很好地压缩成一个数组,例如:daply(dat,。(流域),function(x)quantile(x $ WQ,0.95)) - Richie Cotton
1
数据框通常更容易在未来的聚合和重新加入原始数据方面进行操作。 - hadley

7
我希望我理解你的问题是正确的。这是否是你正在寻找的?
my.df <- data.frame(group = gl(3, 5), var = runif(15))
aggregate(my.df$var, by = list(my.df$group), FUN = function(x) quantile(x, probs = 0.95))

  Group.1         x
1       1 0.6913747
2       2 0.8067847
3       3 0.9643744

编辑

根据Vincent的回答,

aggregate(my.df$var, by = list(my.df$group), FUN = quantile, probs  = 0.95)

同样有效(据说有1001种方法可以做到),顺便提一下,您可以指定所需文件的向量,例如c(0.1, 0.2, 0.3...)表示十分位数。或者您可以尝试使用函数summary来获取一些预定义的统计信息。

aggregate(my.df$var, by = list(my.df$group), FUN = summary)

我以前从未使用过gl... :) - Vincent

5
使用tapply和quantile函数的组合。例如,如果您的数据集看起来像这样:
DF <- data.frame('watershed'=sample(c('a','b','c','d'), 1000, replace=T), wq=rnorm(1000))

使用这个:
with(DF, tapply(wq, watershed, quantile, probs=0.95))

1
Richie:这个“with”编辑真的是一个改进吗?我不介意,但我只是想知道你是否认为那样更优雅,还是有实际的技术好处。 - Vincent
我认为这是个品味问题,虽然如果你想要更加动态一些的话,它可能有其优点。 - Roman Luštrik

3
在Excel中,您需要使用数组公式来使其变得简单。我建议采用以下方式:
{=PERCENTILE(IF($A2:$A6 = Watershed ID, $B$2:$B$6), 0.95)}

第一列是流域ID,第二列是水质值。

另外,请确保将公式输入为数组公式。在输入公式时按Ctrl+Shift+Enter即可。


插入流域ID的值。那只是一个占位符。例如 {=PERCENTILE(IF($A2:$A6 = 50500101, $B$2:$B$6), 0.95)} - Excellll
如果您使用单元格引用来表示流域标识符,那么您可以将公式向下填充到表中的所有标识符。 - Excellll

0

使用data.table包,您可以进行以下操作:

set.seed(42)
#Sample data
dt <- data.table(Watershed = sample(letters[1:2], 100, TRUE), WQ = rnorm(100))

dt[ ,
    j = .(WQ95 = quantile(WQ, .95, na.rm = TRUE),
    by = Watershed]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接