
Average data according to a category (or key or index) wave

jcor
This function averages over such categories and returns the mean and standard error of the mean, in waves described below. Other quantities can be retrieved by adding code after
// get the desired summary statistics
.#pragma rtGlobals=3 // Use modern global access method and strict wave access. function /WAVE averageByKey(waveToAvg, dataKeys[, keyTol]) // Given a wave waveToAvg and a wave dataKeys, // determines the number of unique entries (categories/keys/...) in dataKeys // and averages waveToAvg according to those entries. // The standard error of the mean, # of points averaged, and corresponding // categories are also saved. // e.g. // averageByKey(calibrationData, calibrationSolution) // Key by entry in calibrationSolution // make /n=(numpnts(signal)) signalInt=round(signal); averageByKey(signal,signalInt) // Average to nearest integer // // OUTPUT: // averageByKey(data, keys), produces: // wave data_Keys -- a list of the unique data keys found in keyWave // wave data_Kavg -- the mean of the data corresponding to the keys // wave data_KSE -- the standard error of the mean // wave data_Knum -- the # of points used for calculating the Avg & SD wave waveToAvg wave dataKeys variable keyTol // Optional: the tolerance of keys, e.g. is 1.001 a "1" or not? if (ParamIsDefault(keyTol)) keyTol= 1e-07 endif // get list of unique keys wave keys = getKeys(dataKeys, tol=keyTol, wname=nameOfWave(waveToAvg) + "_Keys") variable nkeys = numpnts(keys) // try to predict memory overflow variable np=numpnts(waveToAvg) if (np*nkeys > 2147000000) abort "averageByKey() was given too many keys / data points. Make a smaller selection." endif // prepare waves for saving summary stats make /d/n=(nkeys)/o $(nameOfWave(waveToAvg) + "_KAvg") /WAVE=out_avg make /d/n=(nkeys)/o $(nameOfWave(waveToAvg) + "_KSE") /WAVE=out_SE make /d/n=(nkeys)/o $(nameOfWave(waveToAvg) + "_Knum") /WAVE=out_n out_avg=nan out_SE=nan out_n=nan // prepare output matrix make /FREE /d/n=(np,nkeys) outmat=nan // each column represents one key & contains only that key's data variable i,colkey for (i=0; i<nkeys; i+=1) SetDimLabel 1, i, $num2str(keys[i]), outmat // label for later sorting endfor // go through the data, insert appropriate results into outmat string Sthiskey for (i=0; i<np; i+=1) Sthiskey = num2str(dataKeys[i]) outmat[i][% $Sthiskey]=waveToAvg[i] endfor // get the desired summary statistics for (i=0; i<nkeys; i+=1) ImageStats /G={0, np-1, i,i} outmat if (V_flag < 0) // probably unnecessary: avoid saving the previous loop's stats abort "averageByKey(): unknown error" endif out_n[i]=V_npnts if (V_npnts>0) // for V_npnts==1, V_sdev is set to NaN out_avg[i]=V_avg out_SE[i]=V_sdev / sqrt(V_npnts) endif endfor return keys end function /WAVE getKeys(keys[, tol, wname]) // Given a list of keys (e.g. laser on/off = 0/1), // return a wave of the unique keys only (in e.g. above, {0,1}) wave keys variable tol // optional, allow 1.0001==1 to be true. string wname // optional name of output wave if (ParamIsDefault(tol)) tol= 1e-07 endif if (ParamIsDefault(wname)) wname= nameOfWave(keys) + "_uniqKeys" endif // create output wave make /d/o/n=0 $wname /WAVE=outw outw=nan // special case of an empty key wave, or one with only NaN/inf wavestats /Q/M=1 keys if (V_npnts==0) return outw endif // go through input wave & save any new entries variable i=0, np=numpnts(keys) do if (getIndex(keys[i], outw, tol=tol) == -1) appendWave(outw, {keys[i]}) SetDimLabel 0, (numpnts(outw)-1), $num2str(keys[i]), outw // label for ease of use (but tol!=0 must be considered) endif i += 1 while (i<np) return outw end function getIndex(v, w, [tol, rev, start]) // Finds the index of the given variable var in the given wave w. // Optional variable tolerance gives the ± acceptance range. Default 1.0E-7. // Optional variable rev searches in reverse if set. // Capable of finding NaNs. // Returns -1 if not found. // see also FindValue variable v wave w variable tol variable rev variable start // default == 0 if (paramIsDefault(tol)) // TODO: change this to an autodetected spacing from w tol = 1.0E-7 elseif (tol < 0) tol = abs(tol) endif variable i, n = numpnts(w) if ((rev)) if (ParamIsDefault(start)) start = n-1 endif if (start < 0) abort "Cannot start at a negative index." // Strictly speaking getIndex() is not responsible for this, but it helps with debugging. endif for (i =start; i >= 0; i -= 1) if (abs(w[i] - v) < tol) return i endif endfor else for (i =start; i < n; i += 1) if (abs(w[i] - v) < tol) return i endif endfor endif return -1 end function appendWave(taker, appendThis) // Concatenate alias. Given a wave "appendThis", appends its data to "taker". 1D waves only. wave taker, appendThis concatenate /NP=0 {appendThis}, taker end

Forum

Support

Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More