Skip to content

statistical::mode bug? #18

@astrorafael

Description

@astrorafael

Hi,

New to Rust here and I was looking for a simple nice statistics package. Using the mode function i discovered that it doesn't work as I expected when there is no elements repetition or bimodal distributions:

use statistical::mode;

fn main() {
    let v: Vec<i32> = [5, 4, 3, 2, 1, 2].into();
    let m = mode(&v);
    assert_eq!(m, Some(2));

    // No mode at all
    let v: Vec<i32> = [5, 4, 3, 2, 1, 0].into();
    let m = mode(&v);
    assert_eq!(m, None);

    // Bimodal, should signal None
    let v: Vec<i32> = [4, 4, 3, 2, 1, 2].into();
    let m = mode(&v);
    assert_eq!(m, None);
}

Tinkering with the source code I devised a fix, which you may consider to incorporate in your repository.

use std::collections::HashMap;
use std::hash::Hash;

pub fn mode<T>(v: &[T]) -> Option<T>
where
    T: Hash + Copy + Eq,
{
    match v.len() {
        0 => None,
        1 => Some(v[0]),
        _ => {
            let mut counter = HashMap::new();
            for x in v.iter() {
                counter.entry(x).and_modify(|c| *c += 1).or_insert(1);
            }
            let mut max = 1;
            let mut mode = None;

            for (val, count) in counter.iter() {
                if *count == max {
                    // Handle multimodal
                    mode = None;
                } else if *count > max {
                    max = *count;
                    mode = Some(**val);
                }
            }
            mode
        }
    }
}

fn main() {
    let v: Vec<i32> = [5, 4, 3, 2, 1, 2].into();
    let m = mode(&v);
    assert_eq!(m, Some(2));

    // No mode at all
    let v: Vec<i32> = [5, 4, 3, 2, 1, 0].into();
    let m = mode(&v);
    assert_eq!(m, None);

    // Bimodal, should signal None
    let v: Vec<i32> = [4, 4, 3, 2, 1, 2].into();
    let m = mode(&v);
    assert_eq!(m, None);
}

Grettings
Rafael

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions