0todd0000 / spm1d

One-Dimensional Statistical Parametric Mapping in Python
GNU General Public License v3.0
61 stars 21 forks source link

Nonparam.anova2onerm error #283

Closed andreivaniskimello closed 4 months ago

andreivaniskimello commented 6 months ago

Hi Todd!

I'm running (in Python) a 2 way Anova with 1 repeated measures in 1 factor (Group - A; Walking condition - B). B is the facotr with repeated measures. I've been able to run parametric "anova2onerm", but I also want also to run the Non-Parametric test (to see if the results differ qualitatively). However, when I run the Non-Parametric this error message appears:

"ValueError: operands could not be broadcast together with shapes (3,101) (3,) "

My Y array is the curves of each Subject for each trial (I'm not using the mean curve along all trial per subject). Could be a unbalanced issue?

Thank you very much for your attention.

Best, André

0todd0000 commented 6 months ago

Thank you for reporting this problem! I've not seen this error before with spm1d. I don't think it is related to design balance because imbalances would be flagged to the user. So I wonder if this might be a version issue... Can you please confirm (1) that you are using Python 3.6 or newer, and (2) that you are using the most recent version of spm1d (version 0.4.28)? If yes to both, please tell me the versions of Python, Numpy and Scipy that you are using and I will try to replicate the error.

andreivaniskimello commented 6 months ago

Thank you for the quick reply, Todd!

I'm using (1) Python 3.8.18, and (2) spm1d 0.4.28, with Numpy 1.24.3, Scipy 1.10.1.

Best, André

0todd0000 commented 6 months ago

Hello, I have tried the versions you mention but am unable to replicate the error. I therefore suspect that there is something odd about the data...

andreivaniskimello commented 6 months ago

Hi, Todd!

Thank you very much for your attention, and I'm sorry for the late reply.

Can you please confirm that you can execute the anova2onerm example script without errors?

The anova2onerm execution is giving this error:

_" UserWarning: WARNING: Only one observation per subject found. Residuals and inference will be approximate. To avoid approximate residuals: (a) Add multiple observations per subject and per condition, and (b) ensure that all subjects and conditions have the same number of observations.

if ((model.dim == 1) or _force_approx0D) and ( design.check_for_singleresponses(dim=model.dim) ): "

However, I am using multiple observations per subject and per condition, but they do not have the same number of observations.

**If that executes without errors, please send the following details regarding your case:

Y.shape = (398, 101) A.shape = (398,) B.shape = (398,) SUBJ.shape = (398,)

(np.unique(Y).size) = 40198 (np.unique(A).size) = 2 (np.unique(B).size) = 2

np.isnan(Y).sum() = 0 np.isnan(A).sum() = 0 np.isnan(B).sum() = 0 np.isnan(SUBJ).sum() = 0 (np.unique(SUBJ).size) = 31

And these are the code lines:

F = spm1d.stats.nonparam.anova2onerm(Y, A, B, SUBJ) FFi = [F.inference(alpha=0.05, iterations = 1000) for F in F]

Best, André

0todd0000 commented 6 months ago

Thank you for confirming these details. I don't see any problems with the array shapes or numbers of unique values.

Just to confirm: is the UserWarning above the only warning? (This is a warning and not an error; warnings will not terminate script execution but errors will.) Ignoring warnings, does the example script run without errors?



To debug further please try the following two points:

(1) Instead of conducting inference in a list comprehension on individual F objects like this:

F = spm1d.stats.nonparam.anova2onerm(Y, A, B, SUBJ)
FFi = [F.inference(alpha=0.05, iterations = 1000) for F in F]

please try conducting inference on the list of F objects like this:

FF = spm1d.stats.nonparam.anova2onerm(Y, A, B, SUBJ)
FFi = FF.inference(alpha=0.05, iterations=1000)



(2) Please copy the full error message into this thread? I understand the meaning of the ValueError message above but I don't know what line of the source code is raising this error. With the full error message I'll be able to narrow down possibilities.

andreivaniskimello commented 6 months ago

Hi Todd!

Just to confirm: is the UserWarning above the only warning? (This is a warning and not an error; warnings will not terminate script execution but errors will.) Ignoring warnings, does the example script run without errors?

Yes, it is only warning. The script run without errors.

(2) I paste here the full error message:

ValueError Traceback (most recent call last) Cell In[38], line 2 1 F = spm1d.stats.nonparam.anova2onerm(Y, A, B, SUBJ) ----> 2 FFi = [F.inference(alpha=0.05, iterations = 1000) for F in F]

Cell In[38], line 2 1 F = spm1d.stats.nonparam.anova2onerm(Y, A, B, SUBJ) ----> 2 FFi = [F.inference(alpha=0.05, iterations = 1000) for F in F]

File c:\Users\andre\anaconda3\lib\site-packages\spm1d\stats\nonparam_snpm.py:274, in _SnPM1Donetailed.inference(self, alpha, iterations, interp, circular, force_iterations, cluster_metric) 273 def inference(self, alpha=0.05, iterations=-1, interp=True, circular=False, force_iterations=False, cluster_metric='MaxClusterIntegral'): --> 274 return super(_SnPM1Donetailed, self).inference(alpha=alpha, iterations=iterations, two_tailed=False, interp=interp, circular=circular, force_iterations=force_iterations, cluster_metric=cluster_metric)

File c:\Users\andre\anaconda3\lib\site-packages\spm1d\stats\nonparam_snpm.py:252, in _SnPM1D.inference(self, alpha, iterations, two_tailed, interp, circular, force_iterations, cluster_metric) 250 ### build secondary PDF: 251 self.permuter.set_metric( cluster_metric ) --> 252 self.permuter.build_secondary_pdf( zstar, circular ) 253 ### assemble clusters and conduct cluster-level inference: 254 clusters = self._get_clusters(zstar, two_tailed, interp, circular, iterations, cluster_metric)

File c:\Users\andre\anaconda3\lib\site-packages\spm1d\stats\nonparam\permuters.py:83, in _Permuter1D.build_secondary_pdf(self, zstar, circular) 82 def build_secondary_pdf(self, zstar, circular=False): ---> 83 self.Z2 = [self.metric.get_max_metric(z, zstar, circular) for z in self.ZZ]

File c:\Users\andre\anaconda3\lib\site-packages\spm1d\stats\nonparam\permuters.py:83, in (.0) 82 def build_secondary_pdf(self, zstar, circular=False): ---> 83 self.Z2 = [self.metric.get_max_metric(z, zstar, circular) for z in self.ZZ]

File c:\Users\andre\anaconda3\lib\site-packages\spm1d\stats\nonparam\metrics.py:35, in _Metric.get_max_metric(self, z, thresh, circular) 34 def get_max_metric(self, z, thresh=3.0, circular=False): ---> 35 return max( self.get_all_cluster_metrics(z, thresh, circular) )

File c:\Users\andre\anaconda3\lib\site-packages\spm1d\stats\nonparam\metrics.py:25, in _Metric.get_all_cluster_metrics(self, z, thresh, circular) 24 def get_all_cluster_metrics(self, z, thresh=3.0, circular=False): ---> 25 L,n = bwlabel(z>thresh) 26 x = [0] 27 if n > 0:

ValueError: operands could not be broadcast together with shapes (3,101) (3,)

(1) please try conducting inference on the list of F objects like this: FF = spm1d.stats.nonparam.anova2onerm(Y, A, B, SUBJ) FFi = FF.inference(alpha=0.05, iterations=1000)

I tried running like that now, and it seemed to have worked! I could even see the clusters. I think that the problem is solved.

Thank you very much for your attention and support, Todd!

Best, André