ClusterDepth
Comparison to permuco R implementation
The implementation to Permuco is similar, but ClusterDepth.jl is more barebone - that is, we dont offer many permutation schemes, focus on the ClusterDepth Algorithm, and don't provide the nice wrappers like clusterLM.
Timing wise, a simple test on 50 subjects, 100 repetitions, 5000 permutations shows the following results:
| timepoints | ClusterDepth.jl | permuco | julia-speedup |
|---|---|---|---|
| 40 | 0.03s | 2.9s | ~100x |
| 400 | 0.14s | 22s | ~160x |
| 4000 | 1.88s | 240s | ~120x |
ClusterDepth.calc_clusterdepthClusterDepth.clusterClusterDepth.clusterdepthClusterDepth.ix_sortUniqueClusterDepth.multicol_minimumClusterDepth.pvalsClusterDepth.pvalsClusterDepth.sign_permute!ClusterDepth.studentt_test!ClusterDepth.studentt_unpairedClusterDepth.troendle
ClusterDepth.calc_clusterdepth — Methodcalc_clusterdepth(data,τ)
returns tuple with three entries: 1:maxLength, maximal clustervalue per clusterdepth head, same for tail
We assume data and τ have already been transformed for one/two sided testing, so that we can do d0.>τ for finding clusters
ClusterDepth.cluster — Methodfinds neighbouring clusters in the vector and returns start + length vectors
if the first and last cluster start on the first/last sample, we dont know their real depth
Input is assumed to be a thresholded Array with only 0/1ClusterDepth.clusterdepth — Methodusing Base: Stateful clusterdepth(rng,data::AbstractArray;τ=2.3, statfun=x->abs.(studentt(x)),permfun=signpermute!,nperm=5000,pvaltype=:troendle)
calculate clusterdepth of given datamatrix.
data:statfunwill be applied on last dimension of data (typically this will be subjects)
Optional
τ: Cluster-forming thresholdnperm: number of permutations, default 5000stat_type: default the one-samplet-test, custom function can be specified (seestatfun!andstatfun)side_type: default::abs- what function should be applied after thestatfun? could be:abs,:square,:positiveto test positive clusters,:negativeto test negative clusters. Custom function can be provided, seesidefun`perm_type: default:signfor one-sample data (e.g. differences), performs sign flips. custom function can be provided, seepermfunpval_type: how to calculate pvalues within each cluster, default:troendle, see?pvalsstatfun/statfun!a function that either takes one or two arguments and aggregates over last dimension. in the two argument case we expect the first argument to be modified inplace and provide a suitable Vector/Matrix.sidefun: defaultabs. Provide a function to be applied on each element of the output ofstatfun.permfunfunction to permute the data, should accept an RNG-object and the data. can be inplace, the data is copied, but the same array is shared between permutationsshow_warnings: defaulttrue- function to suppress warnings, useful for simulations
ClusterDepth.ix_sortUnique — Methodin some sense: argsort(argunique(x)), returns the indices to get a sorted unique of x
ClusterDepth.multicol_minimum — Methodcalculates the minimum in `X` along `dims=2` in the columns specified by àrrayOfIndicearrays` which could be e.g. `[[1,2],[5,6],[3,4,7]]`ClusterDepth.pvals — Methodpvals(data;kwargs...) = pvals(data[2:end],data[1];kwargs...)
pvals(data::AbstractVector,stat::Real;type=:twosided)
calculates pvalues based on permutation results
if called with stat, first entry is assumed to be the observation
ClusterDepth.pvals — MethodCalculate pvals from cluster-depth permutation matrices
ClusterDepth.sign_permute! — MethodPermutation via random sign-flip Flips signs along the last dimension
ClusterDepth.studentt_test! — Methodstudentt_test!(out,x;type=:abs)strongly optimized one-sample t-test function.
Implements: t = mean(x) / ( sqrt(var(x))) / sqrt(size(x,2)-1)
Accepts 2D or 3D matrices, always aggregates over the last dimension
ClusterDepth.studentt_unpaired — Methodstudentt_unpaired(x::AbstractArray, group)Implements a unpaired two groups t-test with unequal variances. 10x as fast as HypothesisTests because we don't allocate that much Use like this:
studentt_unpaired([1,2,1,1,4,5,4],[false,false,false,false,true,true,true])To use with ClusterDepth, you have to "bake-in" the group membership by defining your own method:
grp = ["bla","bla","bla","bla","blub","blub","blub"] .== "blub"
my_statfun = x->studentt_unpaired(x,grp)ClusterDepth.troendle — Methodfunction troendle(perm::AbstractMatrix,stat::AbstractVector;type=:twosided)
Multiple Comparison Correction as in Troendle 1995
perm with size ntests x nperms
stat with size ntests
type can be :twosided (default), :lesser, :greater
Heavily inspired by the R implementation in permuco from Jaromil Frossard
Note: While permuco is released under BSD, the author Jaromil Frossard gave us an MIT license for the troendle and the clusterdepth R-functions.