Skip Menu |

This queue is for tickets about the List-SomeUtils CPAN distribution.

Report information
The Basics
Id: 121490
Status: resolved
Priority: 0/
Queue: List-SomeUtils

People
Owner: Nobody in particular
Requestors: jpierce [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: (no value)
Fixed in: (no value)



Subject: Add some missing stuff: mode
Will return most common value(s), and unlike the mode in Statistics::Descriptive and Statistics::Basic, works with text as well as numbers. sub mode{ my %F; $F{$_}++ foreach @_; my $max = $F{ (sort { $F{$b}<=>$F{$a} } keys %F)[0] }; grep { $F{$_}==$max } keys %F; }
On Mon May 01 14:14:00 2017, JPIERCE wrote: Show quoted text
> Will return most common value(s), and unlike the mode in > Statistics::Descriptive and Statistics::Basic, works with text as well > as numbers. > > sub mode{ > my %F; > $F{$_}++ foreach @_; > my $max = $F{ (sort { $F{$b}<=>$F{$a} } keys %F)[0] }; > grep { $F{$_}==$max } keys %F; > }
Slightly less elegant, but more robust: sub mode{ my %F; $F{$_}++ foreach grep { defined } @_; my $max = $F{ (sort { $F{$b}<=>$F{$a} } keys %F)[0] }; my @modes = grep { $F{$_}==$max } keys %F; return wantarray() ? @modes : (scalar @modes > 1 ? undef : $modes[0]); } This will return undef in scalar context if more than one mode exists. The previous version would permit undef as a valid data point/mode, but in scalar context you'd end up with the number of modes for your data rather than the actual mode, even for a unimodal data set. Alternatively, keep the previous version and simply note in documentation that it must always be called in list context....
On 2017-05-01 19:40:04, JPIERCE wrote: Show quoted text
> On Mon May 01 14:14:00 2017, JPIERCE wrote:
> > Will return most common value(s), and unlike the mode in > > Statistics::Descriptive and Statistics::Basic, works with text as > > well > > as numbers. > > > > sub mode{ > > my %F; > > $F{$_}++ foreach @_; > > my $max = $F{ (sort { $F{$b}<=>$F{$a} } keys %F)[0] }; > > grep { $F{$_}==$max } keys %F; > > }
> > Slightly less elegant, but more robust: > > sub mode{ > my %F; > $F{$_}++ foreach grep { defined } @_; > my $max = $F{ (sort { $F{$b}<=>$F{$a} } keys %F)[0] }; > my @modes = grep { $F{$_}==$max } keys %F; > return wantarray() ? @modes : (scalar @modes > 1 ? undef : > $modes[0]); > } > > This will return undef in scalar context if more than one mode > exists. The previous version would permit undef as a valid data > point/mode, but in scalar context you'd end up with the number of > modes for your data rather than the actual mode, even for a unimodal > data set. > > Alternatively, keep the previous version and simply note in > documentation that it must always be called in list context....
This looks useful, but I think to add any new subs I'd also want to add an XS version to List-SomeUtils-XS. Any chance you'd be up for that? Also, I'm about to move this issue queue to GitHub ...