weighted.quantile <- function(x, w, probs = seq(0, 1, 0.25),
na.rm = FALSE, names = TRUE) {
if (any(probs > 1) | any(probs < 0)) stop("'probs' outside [0,1]")
if (length(w) == 1) w <- rep(w, length(x))
if (length(w) != length(x)) stop("w must have length 1 or be as long as x")
if (isTRUE(na.rm)) {
w <- x[!is.na(x)]
x <- x[!is.na(x)]
}
w <- w[order(x)] / sum(w)
x <- x[order(x)]
cum_w <- cumsum(w) - w * (1 - (seq_along(w) - 1) / (length(w) - 1))
res <- approx(x = cum_w, y = x, xout = probs)$y
if (isTRUE(names)) {
res <- setNames(res, paste0(format(100 * probs, digits = 7), "%"))
}
res
}
权重统一时,加权分位数与常规未加权分位数相同:
x <- rnorm(100)
stopifnot(stopifnot(identical(weighted.quantile(x, w = 1), quantile(x)))
9条答案
按热度按时间hmtdttj41#
以下软件包都有计算加权中位数的函数:“芳香.光”、“等渗”、“利马”、“cwhmisc”、“ergm”、“laeken”、“矩阵统计”、“PSCBS”和“bigvis”(在github上)。
为了找到它们,我使用了'sos'包中非常宝贵的findFn(),它是R内置帮助的扩展。
或者,
第一个月
as???是快捷方式,与
?some.function
是help(some.function)
的快捷方式相同zzwlnbp82#
使用@wkmor1和@Jaitropmange的答案的一些经验。
我已经检查了3个软件包中的3个函数,
isotone
,laeken
和matrixStats
。只有matrixStats
工作正常。其他两个(就像median(rep(x, times=w)
解决方案一样)给出整数输出。只要我计算人口的中位年龄,小数位就很重要。可重现的例子:人口中位年龄的计算
总结
matrixStats::weightedMedian()
是可靠的解决方案nxowjjhe3#
使用相同长度的(整数)权重向量
w
计算向量x
的加权中值:brtdzjyr4#
这只是一个简单的解决方案,几乎可以随时随地使用。
bcs8qyzn5#
很老的帖子,但我只是偶然发现它,并做了一些测试的不同方法.
spatstat::weighted.median()
似乎是大约14倍的速度比median(rep(x, times=w))
,它实际上是显而易见的,如果你想运行函数超过几次.测试是与一个相对较大的调查,约15,000人.uqdfh47h6#
也可以使用
stats::density
创建加权PDF,然后将其转换为CDF,如here所述:那么
my_wtd_q(x, w, .5)
将是加权中位数。还可以更小心地通过重新归一化来确保
density
下的总面积为1。6bc51xsx7#
在 base 中获得 * 加权中位数 * 的一种方法是按值排序,构建权重的
cumsum
,并获得权重的sum * 0.5
处的值。使用简单的输入数据将得到以下结果。
它也可用于其它铁路
与其他方法进行比较。
方法
结果
在这两种情况下,与
median(rep(x, w))
返回的结果相比,只有 isotone 和 GKi 给予相同的结果。iaqfqrcu8#
如果您正在使用
survey
包,假设您已定义调查设计,并且x
是您感兴趣的变量:falq053o9#
我来到这里是为了寻找加权分位数,所以我想我最好把我最终得到的留给未来的读者。自然,使用probs = 0.5将返回加权中位数。
我从MichaelChirico的answer开始,不幸的是它在边缘关闭,然后我决定从
density()
切换到approx()
,最后,我相信我确定了校正因子,以确保与未加权quantile()
的默认算法一致。权重统一时,加权分位数与常规未加权分位数相同:
示例使用与
weighted.mean()
手册页中相同的数据。这是给那些只想得到加权中值的人的: