frange(mtcars$mpg)
## Checking computational equivalence to stats::quantile()
w = alloc(abs(rnorm(1)), 32)
o = radixorder(mtcars$mpg)
for (i in 5:9) print(all_obj_equal(fquantile(mtcars$mpg, type = i),
fquantile(mtcars$mpg, type = i, w = w),
fquantile(mtcars$mpg, type = i, o = o),
fquantile(mtcars$mpg, type = i, w = w, o = o),
quantile(mtcars$mpg, type = i)))
## Demonstaration: weighted quantiles type 7 in R
wquantile7R <- function(x, w, probs = c(0.25, 0.5, 0.75), na.rm = TRUE, names = TRUE) {
if(na.rm && anyNA(x)) { # Removing missing values (only in x)
cc = whichNA(x, invert = TRUE) # The C code first calls radixorder(x), which places
x = x[cc]; w = w[cc] # missing values last, so removing = early termination
}
if(anyv(w, 0)) { # Removing zero weights
nzw = whichv(w, 0, invert = TRUE) # In C, skipping zero weight order statistics is built
x = x[nzw]; w = w[nzw] # into the quantile algorithm, as outlined above
}
o = radixorder(x) # Ordering
wo = w[o]
w_cs = cumsum(wo) # Cumulative sum
sumwp = sum(w) # Computing sum(w) - min(w)
sumwp = sumwp - min(w)
sumwp = sumwp * probs # Target sums of weights for quantile type 7
res = sapply(sumwp, function(tsump) {
j = which.max(w_cs > tsump) # Lower order statistic
hl = (w_cs[j] - tsump) / wo[j] # Index weight of x[j] (h = 1 - hl)
hl * x[o[j]] + (1 - hl) * x[o[j+1L]] # Weighted quantile
})
if(names) names(res) = paste0(as.integer(probs * 100), "%")
res
} # Note: doesn't work for min and max. Overall the C code is significantly more rigorous.
wquantile7R(mtcars$mpg, mtcars$wt)
all.equal(wquantile7R(mtcars$mpg, mtcars$wt),
fquantile(mtcars$mpg, c(0.25, 0.5, 0.75), mtcars$wt))
## Efficient grouped quantile estimation: use .quantile for less call overhead
BY(mtcars$mpg, mtcars$cyl, .quantile, names = TRUE, expand.wide = TRUE)
BY(mtcars, mtcars$cyl, .quantile, names = TRUE)
library(magrittr)
mtcars |> fgroup_by(cyl) |> BY(.quantile)
## With weights
BY(mtcars$mpg, mtcars$cyl, .quantile, w = mtcars$wt, names = TRUE, expand.wide = TRUE)
BY(mtcars, mtcars$cyl, .quantile, w = mtcars$wt, names = TRUE)
mtcars |> fgroup_by(cyl) |> fselect(-wt) |> BY(.quantile, w = mtcars$wt)
mtcars |> fgroup_by(cyl) |> fsummarise(across(-wt, .quantile, w = wt))
Run the code above in your browser using DataLab