R有加权.median()函数吗?

Mic*_*ams 30 r

我正在寻找类似于weighted.mean()的形式.很抱歉发布了这样一个平庸的问题......对R来说很新.我通过搜索找到了一些解决方案,写出了整个功能,但会感谢一些用户友好的东西.

wkm*_*or1 41

以下包都有计算加权中位数的函数:'aroma.light','isotone','limma','cwhmisc','ergm','laeken','matrixStats,'PSCBS'和'bigvis' (在github上).

为了找到它们,我在'sos'包中使用了无价的findFn(),它是R内置帮助的扩展.

findFn('weighted median')
Run Code Online (Sandbox Code Playgroud)

要么,

???'weighted median'

如??? 就是以同样的方式快捷方式?some.functionhelp(some.function)

  • Hmisc也有wtd.quantile :) (7认同)
  • 我不知道 findFn!棒极了! (2认同)

Jai*_*nge 23

x使用(整数)权重的相同长度向量计算向量的加权中值w:

median(rep(x, times=w))
Run Code Online (Sandbox Code Playgroud)

  • 如果权重很大,则会出现性能问题. (4认同)
  • 这仅适用于整数权重。调查数据中的权重通常是小数。 (3认同)
  • 非常糟糕的主意。如果“w”具有非常大的值会发生什么?仅仅为了计算中位数而填充内存是不明智的。 (2认同)

ika*_*sky 21

一些经验使用@ wkmor1和@Jaitropmange的答案.


我从3包检查3个功能,isotone,laeken,和matrixStats.只能matrixStats正常工作.其他两个(就像median(rep(x, times=w)解决方案一样)给出整数输出.只要我计算了人口的年龄中位数,小数就很重要.

可重复的例子.计算人口的中位年龄

df <- data.frame(age = 0:100,
                 pop = spline(c(4,7,9,8,7,6,4,3,2,1),n = 101)$y)

library(isotone)
library(laeken)
library(matrixStats)

isotone::weighted.median(df$age,df$pop)
# [1] 36
laeken::weightedMedian(df$age,df$pop)
# [1] 36
matrixStats::weightedMedian(df$age,df$pop)
# [1] 36.164
median(rep(df$age, times=df$pop))
# [1] 35
Run Code Online (Sandbox Code Playgroud)

摘要

matrixStats::weightedMedian() 是可靠的解决方案

  • 请注意,rep(x,times = w)方法需要整数权重,因此它不适用于您的情况.你可以近似使用:中位数(rep(df $ age,times = 1000*df $ pop)),它给出36.你是否想要小数输出取决于你对中位数的定义. (3认同)
  • 有一个小细节...根据[维基百科上的加权中位数](https://en.wikipedia.org/wiki/Weighted_median)的定义,答案36是正确的。 (2认同)
  • 是的...我们没有比维基百科更好的参考 (2认同)
  • 我不明白这里的讽刺。对同一件事有很多功能,但结果却不同,这不是非常具有破坏性吗?你怎么知道`matrixStats::weightedMedian()` 给出了_可靠的解决方案_?[代码](https://github.com/HenrikBengtsson/matrixStats/blob/master/src/weightedMedian_lowlevel_template.h) 似乎表明它应该产生[加权百分位数方法结果](https://en.wikipedia.org /wiki/Percentile#Weighted_percentile),但这些值与使用此方法的 `spatstat::weighted.median()` 不同,并且对上述问题产生 `35.66291`。 (2认同)
  • 当然,不是选择一种方法来计算加权中位数,我们也可以对所有这些方法使用加权中位数...... (2认同)

R.A*_*eda 8

这只是一个简单的解决方案,几乎可以在任何地方使用。

weighted.median <- function(x, w) {
  w <- w[order(x)]
  x <- x[order(x)]

  prob <- cumsum(w)/sum(w)
  ps <- which(abs(prob - .5) == min(abs(prob - .5)))
  return(x[ps])
}

Run Code Online (Sandbox Code Playgroud)


Hau*_*utu 5

真的很老的帖子,但我刚刚遇到它并对不同的方法进行了一些测试。spatstat::weighted.median()似乎比median(rep(x, times=w))它快 14 倍,如果您想多次运行该函数,它实际上很明显。测试是在一个相对较大的调查中进行的,大约有 15,000 人。