d3-array icon indicating copy to clipboard operation
d3-array copied to clipboard

Weighted quantiles?

Open mbostock opened this issue 8 years ago • 4 comments

I tend to do something like this, but it’s pretty inefficient and requires integer weights:

var values = d3.merge(samples.map(s => d3.range(weight(s)).map(() => value(s))));

A related question is how to expose weighted quantiles as a scale.

mbostock avatar Jan 24 '17 22:01 mbostock

Implemented in https://observablehq.com/d/f7139ebca0286081

it's a bit less performant than d3.quantile since I used sort instead of quickselect. (It might be possible to use quickselect iteratively. [EDIT:] it's probably too difficult, I'm giving up on this aspect.)

Fil avatar Jun 24 '20 19:06 Fil

Also, not sure about the API. The typical use case might be with data=[{value, weight},…] so we would need two accessors. But then, when we have an array of weights (as in the notebook), it would be a clunky accessor (_,i) => weights[i].

Fil avatar Jun 24 '20 20:06 Fil

I added a note about the interpolation method—I'm using R-2, not R-7. My thinking here is that the (possibly non-integer) weights do not correspond to repeated point samples that have by chance yielded the same value, but rather represent contiguous classes (or blocks) of a certain width.

image

We want to interpolate the value only when we are exactly on the edge between two blocks.

Fil avatar Jun 25 '20 07:06 Fil

The API now allows for an optional accessor (last argument of the function), weights can be specified as an accessor or an iterable, and values as an iterable.

Fil avatar Jun 25 '20 07:06 Fil