Let's say I have a dataset array (from the statistics toolbox):
>> myds
myds =
Observation SheepCount
1 88
2 2
3 14
4 12
5 40
I'm putting together data from various sources, so I'd like to set 'Location' to be 4 in all of these observations, before I vertcat this dataset together with others. In a normal matrix, you'd say myds(:, 3) = 4, which would broadcast the 4 into all of the spaces in the matrix.
Is there a way to do that on a dataset without using repmat?
Things I've tried that don't work:
myds(:, 'Location') = 4
myds(:).Location = 4
myds.Location(:) = 4
myds.Location = 4
Things that work:
myds.Location = 4; myds.Location(:) = 4; % have to run both
myds.Location = repmat(4, length(myds), 1);
So, do I have to get over my aversion to repmat? Thanks.
edit: I guess what I actually want is to avoid specifying the dimensions of the array of 4's.
You can try using ones instead of repmat.
myds.Location=4*ones(1,5);
it's not elegant but you can also try:
myds.Location= myds.Observation*0 + 4;
Related
I have some input row. To perform some numerical statistical tests I need a lot of samples of the same size, which are sampled from the input row with or without replacement. I have some very straightforward code, which do it:
inputRow = [1 3 4 2 7 5 8 6];
rowSize = numel(inputRow);
nPermutations = 10;
permutedMatrix = nan(nPermutations,rowSize);
replaceFlag = true;
permutedMatrix(1,:) = inputRow;
for iPerm = 2:nPermutations
permutedMatrix(iPerm,:) = datasample(inputRow,rowSize,'Replace',replaceFlag);
end
My question is: Is it possible to generate desired matrix without for loops?
I hope this helps,
resampling with replacement:
input=[2 3 4 2 3 4];
len=size(input,2);
number_of_permutations=10;
rand_idx=randi(len,1,len*number_of_permutations);
permutation_matrix=zeros(len,number_of_permutations);
permutation_matrix(:)=input(rand_idx);
permutation_matrix=permutation_matrix';
this is reampling without replacement
input=[2 3 4 2 3 4];
len=size(input,2);
number_of_permutations=10;
rand_idx=repmat(randperm(len,len),1,number_of_permutations);
permutation_matrix=zeros(len,number_of_permutations);
permutation_matrix(:)=input(rand_idx);
permutation_matrix=permutation_matrix';
idx=randperm(5)
idx=[1,3,4,2,5]
I know this works like that but I'm curious about is there anyway to get something like this.
idx=[1,3,4,2,5,5,3,2,4,1]
adding one set of array after one array
Is there any way to make that?
One vectorized way would be to create a random array of size (m,n), sort it along each row and get the argsort indices. Each row of those indices would represent a group of randperm values. Here, m would be the number of groups needed and n being the number of elements in each group.
Thus, the implementation would look something like this -
[~,idx] = sort(rand(2,5),2);
out = reshape(idx.',1,[])
Sample run -
>> [~,idx] = sort(rand(2,5),2);
>> idx
idx =
5 1 3 2 4
4 3 2 5 1
>> out = reshape(idx.',1,[])
out =
5 1 3 2 4 4 3 2 5 1
You can use the modulo operation:
n = 5 %maximum value
r = 2 %each element are repeated r times.
res = mod(randperm(r*n),n)+1
I'm learning matlab. I'd like to create a smaller array from a larger one. I know how to do this with simple columns or rows, but I get lost in the nomenclature for m x n arrays / matrices.
Original matrix = 10 x 9
mat_original=ones(10,9) in fact, rather than use all ones.. this may make more sense.. lets use mat_original = magic(10)
How do I create a component matrix say with rows 5 to 8 (all columns)?
mat_rows5to8 = mat_original[5 thru 8; :]
How do I create a component matrix, say with columns 2 to 5, (all rows?)
mat_cols2to5 = mat_original[: ; 2 thru 5 ]
and finally how would I create a sub-component array... say rows 4 thru 7, and columns 5 thru 9 ?
mat_small = mat_original[ 4 thru 7; 5 thru 9 ]
How do you remember this stuff?
No need to remember things when you have Google: Matrix Indexing in MATLAB.
Answers to your questions:
mat_rows5to10 = mat_original(5:8,:)
mat_cols2to5 = mat_original(:,2:5)
mat_small = mat_original(4:7,5:9)
In other words:
output = input(<row_first>:<row_last>,<col_first>:<col_last>)
Leave any of the parameters out to include all.
So if I have a matrix s;
s = [4;5;9;12;3]
and I want to calculate the difference between an entry and it's previous entry plus add the previous difference such that I'll get
s = [ 4 0; 5 1; 9 5; 12 8; 3 -1]
I'm quite new to matlab. I understand a for loop would be required to go through the original matrix
The second column of your result seems to be essentially cumsum(diff(s)). However, that's not "the difference between an entry and its previous entry plus the previous difference"; it's the cumulative sum of differences.
So, if what you want in the second column is the cumulative sum of differences:
result = [s [0; cumsum(diff(s))]];
In matlab you have a lot of functions for working directly with matrix, the one that feeds here is diff and cumsum please visit the matlab documentation, and the functions for concatening like horzcat or vertcat int his case manually to get what you need work like this:
>> s = [4;5;9;12;3]
s =
4
5
9
12
3
Get the vector my_cum_diff which is the difference between elements in a vector
my_cum_diff = [0; cumsum(diff(s))]
my_cum_diff = [0; cumsum(diff(s))]
my_cum_diff =
0
1
5
8
-1
finally concat the two vectors
final_s=[s my_cum_diff]
final_s =
4 0
5 1
9 5
12 8
3 -1
My question has two parts:
Split a given matrix into its columns
These columns should be stored into an array
eg,
A = [1 3 5
3 5 7
4 5 7
6 8 9]
Now, I know the solution to the first part:
the columns are obtained via
tempCol = A(:,iter), where iter = 1:end
Regarding the second part of the problem, I would like to have (something like this, maybe a different indexing into arraySplit array), but one full column of A should be stored at a single index in splitArray:
arraySplit(1) = A(:,1)
arraySplit(2) = A(:,2)
and so on...
for the example matrix A,
arraySplit(1) should give me [ 1 3 4 6 ]'
arraySplit(2) should give me [ 3 5 5 8 ]'
I am getting the following error, when i try to assign the column vector to my array.
In an assignment A(I) = B, the number of elements in B and I must be the same.
I am doing the allocation and access of arraySplit wrongly, please help me out ...
Really it sounds like A is alread what you want--I can't imagine a scenario where you gain anything by splitting them up. But if you do, then your best bet is likely a cell array, ie.
C = cell(1,3);
for i=1:3
C{i} = A(:,i);
end
Edit: See #EitanT's comment below for a more elegant way to do this. Also accessing the vector uses the same syntax as setting it, e.g. v = C{2}; will put the second column of A into v.
In a Matlab array, each element must have the same type. In most cases, that is a float type. An your example A(:, 1) is a 4 by 1 array. If you assign it to, say, B(:, 2) then B(:, 1) must also be a 4 by 1 array.
One common error that may be biting you is that a 4 by 1 array and a 1 by 4 array are not the same thing. One is a column vector and one is a row vector. Try transposing A(:, 1) to get a 1 by 4 row array.
You could try something like the following:
A = [1 3 5;
3 5 7;
4 5 7;
6 8 9]
arraySplit = zeros(4,1,3);
for i =1:3
arraySplit(:,:,i) = A(:,i);
end
and then call arraySplit(:,:,1) to get the first vector, but that seems to be an unnecessary step, since you can readily do that by accessing the exact same values as A(:,1).