Extracting max value from each column in a table - matlab

I have generated a table of data with time in one column with attempts 1-10 in the next series of columns. I want to be able to extract the max value in each attempt for further analysis.
I have tried for table MGA
max = max(MGA(:, []))
I get the following error -- "You cannot subscript a table using only one subscript. Table subscripting requires both row and variable subscripts."

First off: Never do max = max();, you'll overload max, and you won't be able to use it again.
And to answer the question, you can do as follows (notice that I've kept the values in the first columns):
MGA
MGA =
1 5 3 8 9
2 4 7 3 3
3 8 7 6 9
4 8 2 7 3
5 2 2 9 10
6 5 5 10 4
7 5 10 6 2
8 7 4 2 3
9 8 6 2 7
10 8 3 3 5
max_values = [MGA(:,1), max(MGA(:,2:end),[],2)]
max_values =
1 9
2 7
3 9
4 8
5 10
6 10
7 10
8 7
9 8
10 8

Related

Take a column of a matrix and make it a row in kdb

Consider the matrix:
1 2 3
4 5 6
7 8 9
I'd like to take the middle column, assign it to a variable, and replace the middle row with it, giving me
1 2 3
2 5 8
7 8 9
I'm extracting the middle column using
a:m[;enlist1]
which returns
2
5
8
How do I replace the middle row with a? Is a flip necessary?
Thanks.
If you want to update the matrix in place you can use
q)show m:(3;3)#1+til 10
1 2 3
4 5 6
7 8 9
q)a:m[;1]
q)m[1]:a
q)show m
1 2 3
2 5 8
7 8 9
q)
cutting out "a" all you need is:
m[1]:m[;1]
You can use dot amend -
q)show m:(3;3)#1+til 10
1 2 3
4 5 6
7 8 9
q)show a:m[;1]
2 5 8
q).[m;(1;::);:;a]
1 2 3
2 5 8
7 8 9
Can see documentation here:
http://code.kx.com/wiki/Reference/DotSymbol
http://code.kx.com/wiki/JB:QforMortals2/functions#Functional_Forms_of_Amend
Making it slightly more generic where you can define the operation, row, and column
q)m:3 cut 1+til 9
1 2 3
4 5 6
7 8 9
Assigning the middle column to middle row :
q){[ m;o;i1;i2] .[m;enlist i1;o; flip[m] i2 ] }[m;:;1;1]
1 2 3
2 5 8
7 8 9
Adding the middle column to middle row by passing o as +
q){[ m;o;i1;i2] .[m;enlist i1;o; flip[m] i2 ] }[m;+;1;1]
1 2 3
6 10 14
7 8 9

Adding a row to a matrix in Q?

I currently have a 3 by 3 matrix "m":
1 2 3
4 5 6
7 8 9
I would like to add a row to matrix 'm' to have a resultant matrix of:
1 2 3
4 5 6
7 8 9
10 11 12
A matrix in q is just a list of lists where inner lists represent rows.
m: ((1 2 3);(4 5 6);(7 8 9))
In order to add one more row all you have to do is add one more inner list to it:
m: m,enlist 10 11 12
enlist is important here, without it you'll end up with this:
q)((1 2 3);(4 5 6);(7 8 9)),10 11 12
1 2 3
4 5 6
7 8 9
10
11
12
I agree; using 0N!x to view the structure is very useful.
To achieve what you want then you can simply do;
q)show m:3 cut 1+til 9 /create matrix
1 2 3
4 5 6
7 8 9
q)show m,:10 11 12 /join new 'row'
1 2 3
4 5 6
7 8 9
10 11 12
q)

How to Sort by Column [duplicate]

This question already has answers here:
Sorting entire matrix according to one column in matlab
(2 answers)
Closed 7 years ago.
In Matlab, how would I sort the 6th column where the 6th column represents a top score:
8 5 2 9 5 0
4 6 4 9 3 1
5 2 3 1 8 1
8 3 2 1 6 10
To form an output of:
8 3 2 1 6 10
5 2 3 1 8 1
4 6 4 9 3 1
8 5 2 9 5 0
Assuming your matrix is called A,
B = sortrows(A, -6)
Should do a descending order sort based on the 6th column.
See this matlab documentation for more information.

Matlab: creating a matrix whose rows consist of a linspace or similar pattern

Anybody know a fast way to produce a matrix consisting of a linspace for each row? For example, the sort of pattern I'm looking for in this matrix is:
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
...
1 2 3 4 5 6 7 8 9 10
Anyone know any fast tricks to produce this WITHOUT using a for loop?
I just figured this out, so just in case anyone else was troubled by this, we can achieve this exact pattern by:
a=linspace(1,10,10);
b=ones(3,1)*a;
This will give:
>> a = 1 2 3 4 5 6 7 8 9 10
>> b = 1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
You need to use repmat.
Example:
>> B = repmat(1:10,[3 1])
B =
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
You can vary the value of 3 there. You can change it accordingly.
Another shortcut I can recommend is similar to repmat, but you specify a base array first of a = 1:10;. Once you do this, you specify a series of 1s in the first dimension when indexing which should produce a matrix of the same vectors with many rows as you want, where each row consists of the base array a. As such:
%// number of times to replicate
n = 4;
a = 1:10;
a = a(ones(1,n),:);
Result:
a =
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
Insert this command: transpose(ndgrid(1:10,1:n));, where n is the number of rows desired in the result.
You can consider these solutions:
With basic matrix indexing (taken from here)
b=a([1:size(a,1)]' * ones(1,NumToReplicate), :) %row-wise replication
b=a(:, ones(NumToReplicate, 1)) %column-wise replication
With bsxfun:
bsxfun(#times,a,(ones(1,NumToReplicate))') %row-wise replication
bsxfun(#times,a',(ones(1,NumToReplicate))) %column-wise replication
You are welcome to benchmark above two solutions with repmat.

Manipulate specific regions of matrix

I want to make a manipulate a matrix/look-up table in matlab. Here is the Matrix I am working with:
0 5 10 15 20 25 30 35 40 45 50
0 3 4 5 6 4 5 5 5 5 5
20 3 4 5 6 4 5 5 5 5 5
27 3 4 5 6 4 5 5 5 5 5
34 3 4 5 6 4 5 5 5 5 5
41 3 4 5 6 4 5 5 5 5 5
49 3 4 5 6 4 5 5 5 5 5
56 3 4 5 6 4 5 5 5 5 5
63 3 4 5 6 4 5 5 5 5 5
71 3 4 5 6 4 5 5 5 5 5
78 3 4 5 6 4 5 5 5 5 5
85 3 4 5 6 4 5 5 5 5 5
93 3 4 5 6 4 5 5 5 5 5
100 3 4 5 6 4 5 5 5 5 5
The First column and row i want to use as my variables. So for instance if i want to manipulate a certain region, how would I do so? e.g. all values between 5 - 15 (top row) and 20-41 (first column) were to be multiplied by 1.33.
Ideally, i want this to be used in a GUI but I want to get the concept understood first as i'm still a new user to the software.
Thanks for all the help,
Kind regards,
Sam
Build a logical index, using bsxfun to combine the row and column conditions (could also be done with repmat). Then use that index to apply the desired operation to the selected entries.
Let A denote your matrix:
ind = bsxfun(#and, A(1,:)>=5 & A(1,:)<=15, A(:,1)>=20 & A(:,1)<=41);
A(ind) = A(ind)*1.33;
You probably need to create some kind of lookup function or data structure. I would create two vectors for your first row and first column separately from your "data" matrix, and use find() function to look up the corresponding index.
If you know the indices of the values that you want to modify in your matrix, then,
A(3:6,2:4) = 1.33*A(3:6,2:4);
should work.
In this case I would actually use 2 indices, one for each dimension.
I assume your data is in one matrix but it should not be too hard to adjust for the case where you use 2 vectrices and a matrix.
idx1 = A(1,:)>=5 & A(1,:)<=15;
idx2 = A(:,1)>=20 & A(:,1)<=41);
A(idx1,idx2) = A(idx1,idx2)*1.33