Skip to content

Commit

Permalink
error for anova with too few samples for experiment
Browse files Browse the repository at this point in the history
  • Loading branch information
mohawk2 committed Feb 21, 2025
1 parent b524b77 commit 88049d3
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 0 deletions.
1 change: 1 addition & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- fix anova_design_matrix for between-subject >2 values (rest of RT#97925)
- add demo
- remove filt_exp and filt_ma, deprecated in 2011
- now an exception to give anova n-observations <= product of categories in IVs

0.853 2025-01-03
- uses PDL 2.096+ lib/*.pd format for quicker builds
Expand Down
4 changes: 4 additions & 0 deletions lib/PDL/Stats/GLM.pd
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,7 @@ sub PDL::anova_rptd {
# highest ord inter for purely within design, (p-1)*(q-1)*(n-1)
my $factor = (ref $full[-1] ? $full[-1] : $err_ref->[$full[-1]])->dim(1);
my $df = $ret{ "$i_pref$e df" } = $factor * $within_df;
die "${i_pref}residual df = 0" if $df <= 0;
$ret{ "$i_pref$e ms" } = $ret{ "$i_pref$e ss" } / $df;
} elsif (ref $full[$k]) { # unique error term
next EFFECT
Expand All @@ -1066,13 +1067,15 @@ sub PDL::anova_rptd {
= $y->sse(sumover($b_G * $G->transpose)) - $ret{ss_residual};
if ($k != $#full) {
my $df = $ret{"$i_pref$e df"} = $full[$k]->dim(1);
die "residual df = 0" if $df <= 0;
$ret{"$i_pref$e ms"} = $ss / $df;
}
} else { # repeating error term
my $ss = $ret{$k == $#full ? 'ss_subject' : "$i_pref$e ss"}
= $ret{"| $idv->[$full[$k]] |$e ss"};
if ($k != $#full) {
my $df = $ret{"$i_pref$e df"} = $ret{"| $idv->[$full[$k]] |$e df"};
die "residual df = 0" if $df <= 0;
$ret{"$i_pref$e ms"} = $ss / $df;
}
}
Expand All @@ -1095,6 +1098,7 @@ sub PDL::anova_rptd {
= $y->sse( sumover($b_G * $G->transpose) ) - $ret{ss_residual};
my $df0 = $ret{ "| $idv->[$k] | df" } = $ivs_ref->[$k]->dim(1);
$ret{ "| $idv->[$k] || err df" } = $df1;
die "residual df = 0" if $df1 <= 0;
$ret{ "| $idv->[$k] | ms" } = $ret{ "| $idv->[$k] | ss" } / $df0;
}
}
Expand Down
9 changes: 9 additions & 0 deletions t/glm.t
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,15 @@ is_pdl $b_bad->dvrs(ones(6) * .5), pdl( 'BAD -1.17741002251547 -1.17741002251547
';
}

{ # anova with too few samples for experiment (3*2*2 categories, 12 samples)
my $y = pdl '[1 1 2 2 3 3 3 3 4 5 5 5]'; # ratings for 12 apples
my $a = sequence(12) % 3 + 1; # IV for types of apple
my @b = qw( y y y y y y n n n n n n ); # IV for whether we baked the apple
my @c = qw( r g r g r g r g r g r g ); # IV for apple colour (red/green)
eval {$y->anova( $a, \@b, \@c, { IVNM=>[qw(apple bake colour)], PLOT=>0 } )};
like $@, qr/residual df = 0/, 'error when too few sample';
}

{ # anova 1 way
my $d = pdl qw( 3 2 1 5 2 1 5 3 1 4 1 2 3 5 5 );
my $a = qsort sequence(15) % 3;
Expand Down

0 comments on commit 88049d3

Please sign in to comment.