Skip to content

medianIndex/quantileIndex doesn’t handle missing data #275

Description

@mbostock

d3.medianIndex returns one less than the index of the median element. For example:

penguins[d3.medianIndex(penguins, (d) => d.body_mass_g)].body_mass_g // 3600
penguins[d3.medianIndex(penguins, (d) => d.body_mass_g) + 1].body_mass_g // 4050

I don’t think this is the intended behavior, even if we were trying to chose the “lower” element in the case where the array length is even. I expect it to return the index of the median value instead.

d3.median(penguins, (d) => d.body_mass_g) // 4050

Previously #140 #159.

Activity

  1. mbostock commented on May 30, 2023

    @mbostock
    MemberAuthor

    It also seems to returning the last index if there are multiple elements with the median value?

    {
      const sorted = d3.sort(penguins, (d) => d.body_mass_g);
      const i = d3.medianIndex(sorted, (d) => d.body_mass_g);
      return sorted[i - 5].body_mass_g; // 4050
    }
  2. mbostock commented on May 30, 2023

    @mbostock
    MemberAuthor

    Ah ha. The problem is that we’re dropping undefined values in the initial filter:

    values = Float64Array.from(numbers(values, valueof));

    This means that the indexes are indexes into the filtered array, and hence are wrong. If we pre-filter the data the correct result is returned:

    {
      const filtered = penguins.filter((d) => d.body_mass_g);
      const i = d3.medianIndex(filtered, (d) => d.body_mass_g);
      return filtered[i];
    }

    Although, we are still returning the last index of equivalent values (it appears), and I think it would be preferable to return the first. But, any of those would be correct as long as we document it.

  3. changed the title [-]medianIndex/quantileIndex is off by one[/-] [+]medianIndex/quantileIndex is wrong[/+] on May 30, 2023
  4. self-assigned this
    on May 30, 2023
  5. changed the title [-]medianIndex/quantileIndex is wrong[/-] [+]medianIndex/quantileIndex doesn’t handle missing data[/+] on May 30, 2023
  6. Fil commented on May 30, 2023

    @Fil
    Member

    ouch!

      const a = [1, 1, 1, 2, 2, undefined, 2, 3];
      a[d3.medianIndex(a)]; // undefined
    
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn’t working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions