ContextLab / quail

A python toolbox for analyzing and plotting free recall data
http://cdl-quail.readthedocs.io/en/latest/
MIT License
20 stars 10 forks source link

lag CRP analysis crashing #112

Closed jeremymanning closed 5 years ago

jeremymanning commented 5 years ago

I tried running a lag CRP analysis on the "random" condition FRFR data:

import quail as q
data = q.load_egg('exp1.egg')
crp = data.analyze('lagcrp')

I was expecting crp to be a "fried egg" object that I could then plot using

crp.plot()

However, instead the code crashed with the following message (this is using a Docker image based on the Sherlock paper's Docker image, but with Quail upgraded to version 0.2.0):

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-1300-bd4500bf5146> in <module>()
----> 1 crp = fr_random_data.analyze('lagcrp')

/opt/conda/lib/python3.6/site-packages/quail/egg.py in analyze(self, analysis, **kwargs)
    335         Calls analyze function
    336         """
--> 337         return analyze(self, analysis=analysis, **kwargs)
    338 
    339 class FriedEgg(object):

/opt/conda/lib/python3.6/site-packages/quail/analysis/analysis.py in analyze(egg, subjgroup, listgroup, subjname, listname, analysis, position, permute, n_perms, parallel, match, distance, features, ts)
    151         opts.update({'ts' : ts})
    152 
--> 153     return FriedEgg(data=_analyze_chunk(egg, **opts), analysis=analysis,
    154                     list_length=egg.list_length, n_lists=egg.n_lists,
    155                     n_subjects=egg.n_subjects, position=position)

/opt/conda/lib/python3.6/site-packages/quail/analysis/analysis.py in _analyze_chunk(data, subjgroup, subjname, listgroup, listname, analysis, analysis_type, pass_features, features, parallel, **kwargs)
    232         res = p.map(_analysis, chunks)
    233     else:
--> 234         res = [_analysis(c) for c in chunks]
    235 
    236     return pd.concat(res)

/opt/conda/lib/python3.6/site-packages/quail/analysis/analysis.py in <listcomp>(.0)
    232         res = p.map(_analysis, chunks)
    233     else:
--> 234         res = [_analysis(c) for c in chunks]
    235 
    236     return pd.concat(res)

/opt/conda/lib/python3.6/site-packages/quail/analysis/analysis.py in _analysis(c)
    211             else:
    212                 opts.update({'columns' : range(-data.list_length,data.list_length+1)})
--> 213         return pd.DataFrame([analysis(s, features=features, **kwargs)],
    214                             index=index, **opts)
    215 

/opt/conda/lib/python3.6/site-packages/quail/analysis/lagcrp.py in lagcrp_helper(egg, match, distance, ts, features)
    118     if match is 'exact':
    119         opts.update({'features' : 'item'})
--> 120     recmat = recall_matrix(egg, **opts)
    121     if not ts:
    122         ts = egg.pres.shape[1]

/opt/conda/lib/python3.6/site-packages/quail/analysis/recmat.py in recall_matrix(egg, match, distance, features)
     47     if match=='exact':
     48         features=['item']
---> 49         return _recmat_exact(egg.pres, egg.rec, features)
     50     else:
     51         return _recmat_smooth(egg.pres, egg.rec, features, distance, match)

/opt/conda/lib/python3.6/site-packages/quail/analysis/recmat.py in _recmat_exact(presented, recalled, features)
     63             r = r_list.dropna().apply(get_feature).get_values()
     64             r = np.vstack(list(filter(lambda x: x is not np.nan, r)))
---> 65             m = [np.where((p==x).all(axis=1))[0] for x in r]
     66             result[li, :len(m)] = [x[0]+1 if len(x)>0 else np.nan for x in m]
     67     return result

/opt/conda/lib/python3.6/site-packages/quail/analysis/recmat.py in <listcomp>(.0)
     63             r = r_list.dropna().apply(get_feature).get_values()
     64             r = np.vstack(list(filter(lambda x: x is not np.nan, r)))
---> 65             m = [np.where((p==x).all(axis=1))[0] for x in r]
     66             result[li, :len(m)] = [x[0]+1 if len(x)>0 else np.nan for x in m]
     67     return result

AttributeError: 'bool' object has no attribute 'all'
jeremymanning commented 5 years ago

Data are from here: https://github.com/ContextLab/FRFR-analyses/blob/fingerprint-analyses/EL-docker/eggs.tar.gz

paxtonfitzpatrick commented 5 years ago

@jeremymanning this was a bug with handling a list for which there were 0 recalls. I fixed the bug on my fork for now (https://github.com/paxtonfitzpatrick/quail) but would rather look at that subject's data to see why there were zero recalls for the lists causing problems before merging. We should decide if this is a case we want quail to be able to handle or not. Throwing an error here might serve as a good indicator that something went wrong with the automatic transcription or during the experiment.

jeremymanning commented 5 years ago

We should be able to handle cases where the participant didn't recall any words. That occasionally happens with undergraduate participants, and frequently happens in some patient populations-- so we definitely can't assume it's an error. So I'd say: submit a pull request!

paxtonfitzpatrick commented 5 years ago

done!