def table(self): table = fmtxt.Table('lrrrr') table.title(self.title) table.caption("Results based on %i samples" % self._n_samples) table.cell('Comparison') table.cell(fmtxt.symbol('t', df=self._df)) table.cell(fmtxt.symbol('p', df='param')) table.cell(fmtxt.symbol('p', df='corr')) table.cell(fmtxt.symbol('p', df='boot')) table.midrule() p_corr = mcp_adjust(self._p_parametric) stars_parametric = star(self._p_parametric) stars_boot = star(self._p_boot, corr=None) for name, t, p1, pc, s1, p2, s2 in zip(self._comp_names, self.t, self._p_parametric, p_corr, stars_parametric, self._p_boot, stars_boot): table.cell(name) table.cell(t, fmt='%.2f') table.cell(fmtxt.p(p1)) table.cell(fmtxt.p(pc, stars=s1)) table.cell(fmtxt.p(p2, stars=s2)) return table
def clusters(self, p=0.05): """Table with significant clusters""" if self.test_type is LMGroup: raise NotImplementedError else: table = fmtxt.Table('lrrll') table.cells('Effect', 't-start', 't-stop', fmtxt.symbol('p'), 'sig', just='l') table.midrule() for key, res in self.items(): table.cell(key) table.endline() clusters = res.find_clusters(p) clusters.sort('tstart') if self.test_type != anova: clusters[:, 'effect'] = '' for effect, tstart, tstop, p_, sig in clusters.zip( 'effect', 'tstart', 'tstop', 'p', 'sig'): table.cells(f' {effect}', ms(tstart), ms(tstop), fmtxt.p(p_), sig) return table
def reduction_table(self, labels=None, vertical=False): """Table with steps of model reduction Parameters ---------- labels : dict {str: str} Substitute new labels for predictors. vertical : bool Orient table vertically. """ if not self._reduction_results: self.execute() if labels is None: labels = {} n_steps = len(self._reduction_results) # find terms terms = [] for ress in self._reduction_results: terms.extend(term for term in ress.keys() if term not in terms) n_terms = len(terms) # cell content cells = {} for x in terms: for i, ress in enumerate(self._reduction_results): if x in ress: res = ress[x] pmin = res.p.min() t_cell = fmtxt.stat(res.t.max(), stars=pmin) p_cell = fmtxt.p(pmin) else: t_cell = p_cell = '' cells[i, x] = t_cell, p_cell if vertical: t = fmtxt.Table('ll' + 'l' * n_terms) t.cells('Step', '') for x in terms: t.cell(labels.get(x, x)) t.midrule() for i in range(n_steps): t_row = t.add_row() p_row = t.add_row() t_row.cells(i + 1, fmtxt.symbol('t', 'max')) p_row.cells('', fmtxt.symbol('p')) for x in terms: t_cell, p_cell = cells[i, x] t_row.cell(t_cell) p_row.cell(p_cell) else: t = fmtxt.Table('l' + 'rr' * n_steps) t.cell() for _ in range(n_steps): t.cell(fmtxt.symbol('t', 'max')) t.cell(fmtxt.symbol('p')) t.midrule() for x in terms: t.cell(labels.get(x, x)) for i in range(n_steps): t.cells(*cells[i, x]) return t
def table(self, title=None, caption=None): """Table with effects and smallest p-value""" if self.test_type is LMGroup: cols = sorted( {col for res in self.values() for col in res.column_names}) table = fmtxt.Table('l' * (1 + len(cols)), title=title, caption=caption) table.cell('') table.cells(*cols) table.midrule() for key, lmg in self.items(): table.cell(key) for res in (lmg.tests[c] for c in cols): pmin = res.p.min() table.cell(fmtxt.FMText([fmtxt.p(pmin), star(pmin)])) elif self.test_type is anova: table = fmtxt.Table('lllll', title=title, caption=caption) table.cells('Test', 'Effect', fmtxt.symbol(self.test_type._statistic, 'max'), fmtxt.symbol('p'), 'sig') table.midrule() for key, res in self.items(): for i, effect in enumerate(res.effects): table.cells(key, effect) pmin = res.p[i].min() table.cell(fmtxt.stat(res._max_statistic(i))) table.cell(fmtxt.p(pmin)) table.cell(star(pmin)) key = '' else: table = fmtxt.Table('llll', title=title, caption=caption) table.cells('Effect', fmtxt.symbol(self.test_type._statistic, 'max'), fmtxt.symbol('p'), 'sig') table.midrule() for key, res in self.items(): table.cell(key) pmin = res.p.min() table.cell(fmtxt.stat(res._max_statistic())) table.cell(fmtxt.p(pmin)) table.cell(star(pmin)) return table
def anova(self): "Return an ANOVA table" # table head table = fmtxt.Table("l" + "r" * 5) if self.title: table.title(self.title) table.cell() headers = ["SS", "df", "MS"] headers += ["F", "p"] for hd in headers: table.cell(hd, r"\textbf", just="c") table.midrule() # table body for name, F_test in zip(self.names, self.F_tests): table.cell(name) table.cell(fmtxt.stat(F_test.SS)) table.cell(fmtxt.stat(F_test.df, fmt="%i")) table.cell(fmtxt.stat(F_test.MS)) if F_test.F: stars = test.star(F_test.p) table.cell(fmtxt.stat(F_test.F, stars=stars)) table.cell(fmtxt.p(F_test.p)) else: table.cell() table.cell() # residuals if self.X.df_error > 0: table.empty_row() table.cell("Residuals") SS, df, MS = self.residuals table.cell(SS) table.cell(df, fmt="%i") table.cell(MS) table.endline() # total table.midrule() table.cell("Total") SS = np.sum((self.Y.x - self.Y.mean()) ** 2) table.cell(fmtxt.stat(SS)) table.cell(fmtxt.stat(len(self.Y) - 1, fmt="%i")) return table
def anova(self): "Return ANOVA table" if self.show_ems is None: ems = defaults["show_ems"] else: ems = self.show_ems # table head table = textab.Table("l" + "r" * (5 + ems)) if self.title: table.title(self.title) table.cell() headers = ["SS", "df", "MS"] # if ems: headers += ["E(MS)"] headers += ["F", "p"] for hd in headers: table.cell(hd, r"\textbf", just="c") table.midrule() # table body for name, SS, df, MS, F, p in self._results_table: table.cell(name) table.cell(textab.stat(SS)) table.cell(textab.stat(df, fmt="%i")) table.cell(textab.stat(MS)) if F: stars = test.star(p) table.cell(textab.stat(F, stars=stars)) table.cell(textab.p(p)) else: table.cell() table.cell() # total table.midrule() table.cell("Total") table.cell(textab.stat(self.Y.SS)) table.cell(textab.stat(self.Y.N - 1, fmt="%i")) return table
def regression_table(self): """ Not fully implemented! A table containing slope coefficients for all effects. """ # prepare table table = fmtxt.Table("l" * 4) df = self.X.df_error table.cell() table.cell("\\beta", mat=True) table.cell("T_{%i}" % df, mat=True) table.cell("p", mat=True) table.midrule() # q = 1 # track start location of effect in model.full ne = len(self.X.effects) for ie, e in enumerate(self.X.effects): table.cell(e.name + ":") table.endline() for i, name in enumerate(e.beta_labels): # Fox pp. 106 ff. beta = self.beta[q + i] # Evar_pt_est = self.SS_res / df # SEB # SS = (self.values[q+i])**2 T = 0 p = 0 # todo: T/p table.cell(name) table.cell(beta) table.cell(T) table.cell(fmtxt.p(p)) q += e.df if ie < ne - 1: table.empty_row() return table
def test(Y, X=None, against=0, match=None, sub=None, par=True, corr='Hochberg', title='{desc}'): """ One-sample tests. kwargs ------ X: perform tests separately for all categories in X. Against: can be - value - string (category in X) """ ct = celltable(Y, X, match, sub) if par: title_desc = "t-tests against %s" % against statistic_name = 't' else: raise NotImplementedError names = []; ts = []; dfs = []; ps = [] if isinstance(against, str): k = len(ct.indexes) - 1 assert against in ct.cells for id in ct.indexes: label = ct.cells[id] if against == label: baseline_id = id baseline = ct.data[id] for id in ct.indexes: if id == baseline_id: continue names.append(ct.cells[id]) if (ct.within is not False) and ct.within[id, baseline_id]: t, p = scipy.stats.ttest_rel(baseline, ct.data[id]) df = len(baseline) - 1 else: data = ct.data[id] t, p = scipy.stats.ttest_ind(baseline, data) df = len(baseline) + len(data) - 2 ts.append(t) dfs.append(df) ps.append(p) elif np.isscalar(against): k = len(ct.cells) for id in ct.indexes: label = ct.cells[id] data = ct.data[id] t, p = scipy.stats.ttest_1samp(data, against) df = len(data) - 1 names.append(label); ts.append(t); dfs.append(df); ps.append(p) if corr: ps_adjusted = mcp_adjust(ps, corr) else: ps_adjusted = np.zeros(len(ps)) stars = star(ps, out=str) # , levels=levels, trend=trend, corr=corr if len(np.unique(dfs)) == 1: df_in_header = True else: df_in_header = False table = fmtxt.Table('l' + 'r' * (3 - df_in_header + bool(corr))) table.title(title.format(desc=title_desc)) if corr: table.caption(_get_correction_caption(corr, k)) # header table.cell("Effect") if df_in_header: table.cell([statistic_name, fmtxt.texstr(dfs[0], property='_'), ], mat=True) else: table.cell(statistic_name, mat=True) table.cell('df', mat=True) table.cell('p', mat=True) if corr: table.cell(fmtxt.symbol('p', df=corr)) table.midrule() # body for name, t, mark, df, p, p_adj in zip(names, ts, stars, dfs, ps, ps_adjusted): table.cell(name) tex_stars = fmtxt.Stars(mark, of=3) tex_t = fmtxt.texstr(t, fmt='%.2f') table.cell([tex_t, tex_stars]) if not df_in_header: table.cell(df) table.cell(fmtxt.p(p)) if corr: table.cell(fmtxt.p(p_adj)) return table
def clusters(self, p=0.05): """Table with significant clusters""" if self.test_type is TestType.TWO_STAGE: raise NotImplementedError else: table = fmtxt.Table('lrrrrll') table.cells('Effect', 't-start', 't-stop', fmtxt.symbol(self._statistic, 'max'), fmtxt.symbol('t', 'peak'), fmtxt.symbol('p'), 'sig', just='l') table.midrule() for key, res in self.items(): table.cell(key) table.endline() clusters = res.find_clusters(p, maps=True) clusters.sort('tstart') if self.test_type is not TestType.MULTI_EFFECT: clusters[:, 'effect'] = '' for effect, tstart, tstop, p_, sig, cmap in clusters.zip('effect', 'tstart', 'tstop', 'p', 'sig', 'cluster'): max_stat, max_time = res._max_statistic(mask=cmap != 0, return_time=True) table.cells(f' {effect}', ms(tstart), ms(tstop), fmtxt.stat(max_stat), ms(max_time), fmtxt.p(p_), sig) return table
def test_p(): assert str(fmtxt.p(.02)) == '.020' assert str(fmtxt.p(.2, stars=True)) == '.200 ' assert str(fmtxt.p(.0119, stars=True)) == '.012* ' assert str(fmtxt.p(.0001, stars=True)) == '< .001***'
def anova(self, title="ANOVA", empty=True, ems=False): """ returns an ANOVA table for the linear model """ X = self.X values = self.beta * self.X.full if X.df_error == 0: e_ms = hopkins_ems(X) elif hasrandom(X): err = "Models containing random effects need to be fully " "specified." raise NotImplementedError(err) else: e_ms = False # table head table = fmtxt.Table("l" + "r" * (5 + ems)) if title: table.title(title) if not isbalanced(X): table.caption("Warning: model is unbalanced, use anova class") table.cell() headers = ["SS", "df", "MS"] if ems: headers += ["E(MS)"] headers += ["F", "p"] for hd in headers: table.cell(hd, r"\textbf", just="c") table.midrule() # MS for factors (Needed for models involving random effects) MSs = {} SSs = {} for e in X.effects: idx = X.full_index[e] SSs[e] = SS = np.sum(values[:, idx].sum(1) ** 2) MSs[e] = SS / e.df # table body results = {} for e in X.effects: MS = MSs[e] if e_ms: e_EMS = e_ms[e] df_d = sum(c.df for c in e_EMS) MS_d = sum(MSs[c] for c in e_EMS) e_ms_name = " + ".join(repr(c) for c in e_EMS) else: df_d = self.df_res MS_d = self.MS_res e_ms_name = "Res" # F-test if MS_d != False: F = MS / MS_d p = 1 - scipy.stats.distributions.f.cdf(F, e.df, df_d) stars = test.star(p) tex_stars = fmtxt.Stars(stars) F_tex = [F, tex_stars] else: F_tex = None p = None # add to table if e_ms_name or empty: table.cell(e.name) table.cell(SSs[e]) table.cell(e.df, fmt="%i") table.cell(MS) if ems: table.cell(e_ms_name) table.cell(F_tex, mat=True) table.cell(fmtxt.p(p)) # store results results[e.name] = {"SS": SS, "df": e.df, "MS": MS, "E(MS)": e_ms_name, "F": F, "p": p} # Residuals if self.df_res > 0: table.cell("Residuals") table.cell(self.SS_res) table.cell(self.df_res, fmt="%i") table.cell(self.MS_res) return table