I have several waves in a table that I would like to perform several operations on , row by row across the several columns and store the results in a new wave. For example compute the averages of the first point, second point etc. across waves and have those values stored in a new wave. I've been experimenting with the Wavestats function but I can't seem to get it to do exactly what I want. Any suggestions?
If the wave scaling is equivalent, you can use the Average Waves package. This will make a new wave containing the averages of each row. If you have different wave scaling, the package doesn't work in this way. If you're doing something more tricky (as per your last question), wavestats /q is probably what you want and you need to store V_avg value in your new wave. Maybe the best thing is to post a pxp (simplified with less data) so that someone can help.
If the waves are all of the same dimensions you might find it beneficial to pack them into a 2D matrix (see the Concatenate operation) and then use MatrixOP that can in one line compute the averages of all the rows.
The built-in package worked great for averaging across each column but what if I would like to do additional operations like finding the st.dev or max/min values? Am I limited to working with the Matrix functions at this point?
The average waves package will calculate s.d. It will also calculate s.e.m. or 95% CI row-by-row. I don't know offhand how to find min and max by row in a matrix. I think for the mean you can do by sumRows(w) / numCols(w) in MatrixOP. Hopefully others will chime in.
I've run into similar issues recently, and found that a good general workaround is to iterate through the matrix using a for loop to extract single rows or columns. Then, you can apply any sort of analysis that works well (or only) with 1D waves, such as wavestats.
For example:
wave matrix variablei for(i=0;i<dimsize(matrix,0);i+=1) make/o/n=(dimsize(matrix,1)) temp
temp = matrix[i][p] // your 1D analysis on "temp" here endfor killwaves temp
If you want to keep the extracted 1D waves, instead of overwriting temp you can use a string that depends on i as a name for the new wave, e.g.:
string name = "row_"+num2str(i) make/o/n=(dimsize(matrix,1)$name
wave matrix variablei for(i=0;i<dimsize(matrix,0);i+=1) make/o/n=(dimsize(matrix,1)) temp
temp = matrix[i][p] // your 1D analysis on "temp" here endfor killwaves temp
Actually this is a very good example of code that may work but is far from ideal in terms of performance. Here are a few things that you can do to streamline it:
(1) your loop does not change the dimensions of the wave matrix so keep the upper limit of the loop from being evaluated as a function on each iteration:
(2) it is normally not a good idea to allocate a wave inside the loop unless you have to do so. In this case the make command could be factored out of the loop so the code should look like:
Variable rows=DimSize(matrix,0) Variable cols=DimSize(matrix,1) Make/o/n=(cols) temp for(i=0;i<rows;i+=1)
temp = matrix[i][p] // your 1D analysis on "temp" here endfor
(3) you can improve the above using MatrixOP:
Variable rows=DimSize(matrix,0) for(i=0;i<rows;i+=1) MatrixOP/O temp=row(matrix,i)^t // your 1D analysis on "temp" here endfor
February 25, 2015 at 01:33 pm - Permalink
A.G.
WaveMetrics, Inc.
February 25, 2015 at 02:52 pm - Permalink
February 25, 2015 at 07:31 pm - Permalink
February 25, 2015 at 11:42 pm - Permalink
For example:
variable i
for(i=0;i<dimsize(matrix,0);i+=1)
make/o/n=(dimsize(matrix,1)) temp
temp = matrix[i][p]
// your 1D analysis on "temp" here
endfor
killwaves temp
If you want to keep the extracted 1D waves, instead of overwriting temp you can use a string that depends on i as a name for the new wave, e.g.:
make/o/n=(dimsize(matrix,1) $name
March 20, 2015 at 08:24 am - Permalink
Actually this is a very good example of code that may work but is far from ideal in terms of performance. Here are a few things that you can do to streamline it:
(1) your loop does not change the dimensions of the wave matrix so keep the upper limit of the loop from being evaluated as a function on each iteration:
Variable cols=DimSize(matrix,1)
for(i=0;i<rows;i+=1)
(2) it is normally not a good idea to allocate a wave inside the loop unless you have to do so. In this case the make command could be factored out of the loop so the code should look like:
Variable cols=DimSize(matrix,1)
Make/o/n=(cols) temp
for(i=0;i<rows;i+=1)
temp = matrix[i][p]
// your 1D analysis on "temp" here
endfor
(3) you can improve the above using MatrixOP:
for(i=0;i<rows;i+=1)
MatrixOP/O temp=row(matrix,i)^t
// your 1D analysis on "temp" here
endfor
March 20, 2015 at 08:48 am - Permalink