display a numeric mat as dataset (with Row/Col Names) in MATLAB - matlab

I'm not very familiar with datasets / displaying data in a readable format in Matlab. I have a numeric matrix with say 4 cols and I need to display it as:
mydata1 = [100 200 400 40] ;
mydata2 = [1 2 3 4 ] ;
display it as -->
CovA CovB CovC CovD
Sys1 100 200 400 40
Sys2 1 2 3 4
I am guessing datasets would help me implement this. Once converted, I'm hoping to publish this dataset with others. Thanks!

DATASET constructs data column-wise. Consequently, you can either accept that everything is transposed, i.e.
ds = dataset({mydata1','sys1'},{mydata2','sys2'},'obsNames',...
{'CovA','CovB','CovC','CovD'})
ds =
sys1 sys2
CovA 100 1
CovB 200 2
CovC 400 3
CovD 40 4
or you construct the dataset rather inconveniently by first catenating mydata:
mm = [mydata1;mydata2];
dataset(mm(:,1),mm(:,2),mm(:,3),mm(:,4),'varNames',...
{'CovA','CovB','CovC','CovD'},'obsNames',{'sys1','sys2'})
ans =
CovA CovB CovC CovD
sys1 100 200 400 40
sys2 1 2 3 4

This will display a matrix as a table in matlab
http://www.mathworks.com/matlabcentral/fileexchange/27384-disptable-display-matrix-with-column-or-row-labels

Related

Reshape array in octave / matlab

I'm trying to reshape an array but I'm having some issues.
I have an array see image below and I'm trying to get it to look like / follow the pattern in the row highlighted in yellow. (note: I'm not trying to calculate the array but reshape it so it follows a pattern)
aa=[1:5;10:10:50;100:100:500]
aa_new=reshape(aa',[1 numel(aa)])
aa_new produces:
1 2 3 4 5 10 20 30 40 50 100 200 300 400 500
I'm trying to get:
1 2 3 4 5 50 40 30 20 10 100 200 300 400 500
Reverse the column numbers of every second row i.e.
aa(2:2:end,:) = aa(2:2:end, end:-1:1);
Now you're good to go with reshaping:
aa = reshape(aa.', 1, []);

How to avoid for loop in Matlab when building a new matrix from a database

I have a matrix with two columns with about 500 rows. The values of first column vary from 1 to 48. This means that there are repeating numbers in the first column.
I need to make to build a new matrix with 48 rows that each row includes information for a specific number in column 1. For example consider the following data:
x = [ 3 500
5 400
3 200
1 100
1 1100
2 450
3 890
1 110
2 800
....]
So, the out put matrix should be:
Output = [100 1100 110 ...0 0 0; 450 800 ... 0 0 0; 8200 890 0 0 0 ...; 0 0 0];
I know how to do it using for loop but I need to do it without a for loop.
I used the following lines
XX = X(:,2);
Output = XX(X(:,1)==(1:48)');
But it did no work because the number of rows in the new matrix is not the same.
Any help is appreciated.
You can do this with the sub2ind function, I recommend reading the documentation to understand how this works. We'll place all the x(:,2) values into a matrix M. The row that each value belongs in depends on the x(:,1) values, so we must determine which column the value belongs to.
Below j is calculated such that j(k) is equal to the number of times x(k,1) occurs in the vector x(1:k,1). This will be the column we want to place the value x(k,2) into.
x = [ 3 500
5 400
3 200
1 100
1 1100
2 450
3 890
1 110
2 800];
j = sum(triu(x(:,1)==x(:,1)')); % Calculate the column each value should be placed into
M = zeros(max(x(:,1)), max(j)); % Set up the empty matrix
ind = sub2ind(size(M), x(:,1), j(:)); % Get linear indices from subscripts
M(ind) = x(:,2)
M =
100 1100 110
450 800 0
500 200 890
0 0 0
400 0 0

Weighted Random number?

How can I randomize and generate numbers from 0-50 in matrix of 5x5 with SUM or each row printed on the right side?
+
is there any way to give weight to individual numbers before generating the numbers?
Please help
Thanks!
To generate a random matrix of integers between 0 and 50 (sampled with replacement) you could use
M = randint(5,5,[0,50])
To print the matrix with the sum of each row execute the following command
[M sum(M,2)]
To use a different distribution there are a number of techniques but one of the easiest is to use the datasample function from the Statistics and Machine Learning toolbox.
% sample from a truncated Normal distribution. No need to normalize
x = 0:50;
weights = exp(-0.5*(x-25).^2 / 5^2);
M = reshape(datasample(x,25,'Weights',weights),[5,5])
Edit:
Based on your comment you want to perform random sampling without replacement. You can perform such a random sampling without replacement if the weights are non-negative integers by simulating the classic ball-urn experiment.
First create an array containing the appropriate number of each value.
Example: If we have the values 0,1,2,3,4 with the following weights
w(0) = 2
w(1) = 3
w(2) = 5
w(3) = 4
w(4) = 1
Then we would first create the urn array
>> urn = [0 0 1 1 1 2 2 2 2 2 3 3 3 3 4];
then, we would shuffle the urn using randperm
>> urn_shuffled = urn(randperm(numel(urn)))
urn_shuffled =
2 0 4 3 0 3 2 2 3 3 1 2 1 2 1
To pick 5 elements without replacement we would simple select the first 5 elements of urn_shuffled.
Rather than typing out the entire urn array, we can construct it programatically given an array of weights for each value. For example
weight = [2 3 5 4 1];
urn = []
v = 0
for w = weight
urn = [urn repmat(v,1,w)];
v = v + 1;
end
In your case, the urn will contain many elements. Once you shuffle you would select the first 25 elements and reshape them into a matrix.
>> M = reshape(urn_shuffled(1:25),5,5)
To draw random integer uniformly distributed numbers, you can use the randi function:
>> randi(50,[5,5])
ans =
34 48 13 28 13
33 18 26 7 41
9 30 35 8 13
6 12 45 13 47
25 38 48 43 18
Printing the sum of each row can be done by using the sum function with 2 as the dimension argument:
>> sum(ans,2)
ans =
136
125
95
123
172
For weighting the various random numbers, see this question.

Matlab loop to convert N x 1 matrix to 60 x 4718 matrix

I am a novice at Matlab and am struggling a bit with creating a loop that will a convert a 283080 x 2 matrix - column 1 lists all stockID numbers (each repeated 60 times) and column 2 contains all lagged monthly returns (60 observations for each stock) into a 60 x 4718 matrix with a column for each stockID and its corresponding lagged returns falling in 60 rows underneath each ID number.
My aim is to then try to calculate a variance-covariance matrix of the returns.
I believe I need a loop because I will be repeating this process over 70 times as I have multiple data sets in this same current format
Thanks so much for the help!
Let data denote your matrix. Then:
aux = sortrows(data,1); %// sort rows according to value in column 1
result = reshape(aux(:,2),60,[]); %// reshape second column as desired
If you need to insert the stockID values as headings (first row of result), add this as a last line:
result = [ unique(aux(:,1)).'; result ];
A simple example, replacing 60 by 2:
>> data = [1 100
2 200
1 101
2 201
4 55
3 0
3 33
4 56];
>> aux = sortrows(data,1);
>> result = reshape(aux(:,2),2,[])
>> result = [ unique(aux(:,1)).'; result ];
result =
1 2 3 4
100 200 0 55
101 201 33 56

Sorting the columns of a matrix by "largest element" in matlab

In matlab, how can I sort a matrices columns in ascending order by the largest element in a given column.
For example, given a matrix A=[1 300 5; 100 1 2; 2 200 7], I would like to output A=[300 1 5; 1 100 2; 200 2 7].
I can do this using a for loop, but I've been hammered with the idea that I should always look for a matrix operation to do anything in matlab.
Find maxima per column in A and sort them. We need the indices of the sort (I).
>> [sortedmaxs,I]=sort(max(A,[],1),'descend')
sortedmaxs =
300 100 7
I =
2 1 3
Sort A based on the indices I:
>> Asort=A(:,I)
Asort =
300 1 5
1 100 2
200 2 7
So in short, you simply need these two lines:
[~,I]=sort(max(A,[],1),'descend');
Asort=A(:,I);