I'm looking for something similar in form to weighted.mean()
. I've found some solutions via search that write out the entire function but would appreciate something a bit more user friendly.
For a weighted median we change how the middle is found; instead of finding the middle value we are looking for the middle weight and then the median is the associated value for that weight. Here's a very high-level algorithm: Sort the values. Add up the weights for the values in order (i.e. a running sum of weight).
If the total number of occurrences (let's call it 'n', i.e. the sum of the frequencies / the total number of students) is odd, then the median is the ((n+1) / 2)-th value. If n is even, then the median is the average of the (n/2)-th and the ((n/2) + 1)-th value.
Real Statistics Function: The weighted median can also be calculated using the function MED(R1, R2) where R1 contains the elements in S and R2 contains the elements in W. If R2 is omitted then the ordinary median is returned, i.e. MEDIAN(R1).
Weighted Median (WM) filters have the robustness and edge preserving capability of the classical median filter and resemble linear FIR filters in certain properties. Furthermore, WM filters belong to the broad class of nonlinear filters called stack filters.
The following packages all have a function to calculate a weighted median: 'aroma.light', 'isotone', 'limma', 'cwhmisc', 'ergm', 'laeken', 'matrixStats, 'PSCBS', and 'bigvis' (on github).
To find them I used the invaluable findFn() in the 'sos' package which is an extension for R's inbuilt help.
findFn('weighted median')
Or,
???'weighted median'
as ??? is a shortcut in the same way ?some.function
is for help(some.function)
Some experience using the answers from @wkmor1 and @Jaitropmange.
I've checked 3 functions from 3 packages, isotone
, laeken
, and matrixStats
. Only matrixStats
works properly. Other two (just as the median(rep(x, times=w)
solution) give integer output. As long as I calculated median age of populations, decimal places matter.
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
matrixStats::weightedMedian()
is the reliable solution
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With