Используя источник из Deleet и данные из Икашницкий , взвешенная медиана может быть вычислена в base с:
df <- data.frame(age = 0:100,
pop = spline(c(4,7,9,8,7,6,4,3,2,1),n = 101)$y)
medianWeighted <- function(x, w) {
x <- aggregate(w[w>0] ~ x[w>0], FUN=sum)
approxfun(filter(c(0,cumsum(x$w)/sum(x$w)), c(.5,.5), sides=1)[-1], x$x)(.5)
}
medianWeighted(df$age,df$pop) #Interpolates between observed Numbers
#[1] 36.164
medianWeightedI <- function(x, w) {
w <- w[order(x)]
x <- x[order(x)]
x[which.min(abs(filter(c(0,cumsum(w)/sum(w)), c(.5,.5), sides=1)[-1] - 0.5))]
}
medianWeightedI(df$age,df$pop) #Takes only numbers which have been observed
#[1] 36
Если вы также хотели вычислить взвешенные квантили .
quantileWeighted <- function(x, w, probs = seq(0, 1, 0.25)) {
x <- aggregate(w[w>0] ~ x[w>0], FUN=sum)
approxfun(filter(c(0,cumsum(x$w)/sum(x$w)), c(.5,.5), sides=1)[-1], x$x, rule=2)(probs)
}
quantileWeighted(df$age, df$pop)
#[1] 0.00000 20.21336 36.16400 55.98371 100.00000
quantileWeightedI <- function(x, w, probs = seq(0, 1, 0.25)) {
x <- aggregate(w[w>0] ~ x[w>0], FUN=sum)
stepfun(cumsum(x$w[-nrow(x)])/sum(x$w[-nrow(x)]), x$x)(probs)
}
quantileWeightedI(df$age, df$pop)
#[1] 0 20 36 56 100