Matlab indexing within eval - matlab

I would like to change values within an dataset using eval. It shlould be in a way thet every second value is changed to the one before.
Short example:
A = magic(6)
ds = mat2dataset(A) % original dataset
ds.A1(2:2:end) = ds.A1(1:2:end) % dataset after change
That's the way I would like to do it. Now I need to use the variables letter and number which are assigned previous in the function.
letter = 'A'
number = '1'
eval([strcat('ds.', letter, number)]) % now gives me all values.
This is exactly the point where I would like to index the (1:2:end) to get just the indexed values.
Does one of you have a good idea how to index within the eval function? I would also prefer other ways of doing it if you have on.
Thanks a lot!

1) Don't use eval to achieve dynamic fieldnames:
h=ds.([letter, number])
2) Double indexing is not possible, you need two lines to achieve it.
h(1:2:end)

Related

How can I use cellarrays instead of dynamic variables in matlab?

I have the following problem:
I have two arrays called Variable_1 and Variable_2 (same size 8x3, only different values). I need to make calculations with the values inside the array and store the result in a new array. The calculation is the same for both arrays.
Right now, I solved it with 2 for-loops.
for i = 1:size(Variable_1,1)
Calculation_1 = 5 * Variable_1(i,1);
Result_1(i,:) = Calculation_1;
end
for i = 1:size(Variable_2,1)
Calculation_2 = 5 * Variable_2(i,1);
Result_2(i,:) = Calculation_2;
end
I want to get rid of two separate for-loops and do it with one loop or a loop in a loop. The name "Variable_x" needs to be kinda dynamical. It is different for every run in the outer for-loop. First, it is Variable_1 and matlab has to look in the array "Variable_1" at position i. Later, it is Variable_2 and it has to look in another array, here called "Variable_2".
I know that I shouldn't use dynamic variables and however I didn't found a solution anyway. Maybe it works with Cellarrays but I dont't know exactly how I use them in this specific case.
It is kinda hard to explain, so feel free to ask questions if you have one. I am really looking forward for any suggestions.

Matlab For Cycle, selecting variables named with incremental numbers

I have a number of vectors containing data that i have to elaborate in the same way, they are named in this fashion: "data1", "data2" ecc... I would like to automatize the process with a for cycle, how can i "select" iteratively the variables using the index?
For example, the first line of my elaboration is an assignment like "x = data1", i want the second cycle to do "x = data2" and so on.
Thank you in advance
You can use a combination of strcat and num2str to create the name of the variable
i = 1;
name = strcat("data",int2str(i));
Thus putting it inside a for-loops which updates i will continuously change the name. Next you can use eval to evaluate the name
x = eval(name);
In total
for i = 1:n
name = strcat("data",int2str(i));
x = eval(name);
end
NOTE 1: It is in general considered bad practice to create variable names this way. You would have been much better off with saving all variables in the same array. As linked by Luis Mendo in the comments.
NOTE 2: It is generally recognised as a for-loop, not a for-cycle :D

MATLAB : Alphanumeric character string extraction

As a foreword, I have been searching for solutions to this, and I have tried a myriad of codes but none of them work for the specific case.
I have a variable that is the registration number of different UK firms. The data was originally from Stata, and I had to use a code to import non-numeric data into Matlab. This variable (regno) is numeric up until observation 18000 (approx). From then it becomes registration numbers with both letters and numbers.
I wrote a very crude loop that grabbed the initial variable (cell), took out the double quotations, and extracted the characters into a another matrix (double). The code is :
regno2 = strrep(regno,'"','');
regno3 = cell2mat(regno2);
regno4 = [];
for i = 1:size(regno3,1);
regno4(i,1) = str2double(regno3(i,1:8));
end
For the variables with both letters and numbers I get NaN. I need the variables as a double in order to use them as dummy indicator variables in MatLab. Any ideas?
Thanks
Ok I'm not entirely sure about whether you need letters all the time, but here regular expressions would likely perform what you want.
Here is a simple example to help you get started; in this case I use regexp to locate the numbers in your entries.
clear
%// Create dummy entries
Case1 = 'NI000166';
Case2 = '12ABC345';
%// Put them in a cell array, like what you have.
CasesCell = {Case1;Case2};
%// Use regexp to locate the numbers in the expression. This will give the indices of the numbers, i.e. their position within each entry. Note that regexp can operate on cell arrays, which is useful to us here.
NumberIndices = regexp(CasesCell,'\d');
%// Here we use cellfun to fetch the actual values in each entry, based on the indices calculated above.
NumbersCell = cellfun(#(x,y) x(y),CasesCell,NumberIndices,'uni',0)
Now NumbersCell looks like this:
NumbersCell =
'000166'
'12345'
You can convert it to a number with str2num (or srt2double) and you're good to go.
Note that in the case in which you have 00001234 or SC001234, the values given by regexp would be considered as different so that would not cause a problem. If the variables are of different lenghts and you then have similar numbers, then you would need to add a bit of code with regexp to consider the letters.
Hope that helps! If you need clarifications or if I misunderstood something please tell me!

Create a loop using part of variable name in MATLAB

I am a beginner in Matlab and have not been able to find an answer to my question so far. Your help will definitely be very much appreciated.
I have 70 matrices (100x100), named SUBJ_1, SUBJ_2 etc. I would like to create a loop so that I would calculate some metrics (i.e. max and min values) for each matrix, and save the output in a 70x2 result matrix (where each row would correspond to the consecutively named SUBJ_ matrix).
I am struggling with both stages - how to use the names of individual variables in a 'for' loop and how to properly save individual outputs in a combined array.
Many thanks and all the best!
Don't use such variable names, create a big cell array named SUBJ and put each Matrix in it.
r=zeros(numel(SUBJ),2)
for idx=1:numel(SUBJ)
r(idx,1)=min(min(SUBJ{idx}))
r(idx,2)=max(max(SUBJ{idx}))
end
min and max are called twice because first call creates maximum among rows, second call among columns.
Even though this is in principle possible in Matlab, I would not recommend it: too slow and cumbersome to implement.
You could instead use a 3-D matrix (100x100x70) SUBJ which would contain all the SUBJ_1 etc. in one matrix. This would allow you to calculate min/max etc. with just one line of code. Matlab will take care of the loops internally:
OUTPUT(:,1) = min(min(SUBJ,[],1)[],2);
OUTPUT(:,2) = max(max(SUBJ,[],1)[],2);
Like this, OUTPUT(1,1) contains min(min(SUBJ(:,:,1))) and so on...
As to how to use the names of individual variables in a 'for' loop, here gives an example:
SUBJ = [];
for idx = 1:70
term = eval(['SUBJ_',num2str(idx)]);
SUBJ = [SUBJ; max(max(term)),min(min(term))];
end

Concatenate equivalent in MATLAB for a single value

I am trying to use MATLAB in order to generate a variable whose elements are either 0 or 1. I want to define this variable using some kind of concatenation (equivalent of Java string append) so that I can add as many 0's and 1's according to some upper limit.
I can only think of using a for loop to append values to an existing variable. Something like
variable=1;
for i=1:N
if ( i%2==0)
variable = variable.append('0')
else
variable = variable.append('1')
i=i+1;
end
Is there a better way to do this?
In MATLAB, you can almost always avoid a loop by treating arrays in a vectorized way.
The result of pseudo-code you provided can be obtained in a single line as:
variable = mod((1:N),2);
The above line generates a row vector [1,2,...,N] (with the code (1:N), use (1:N)' if you need a column vector) and the mod function (as most MATLAB functions) is applied to each element when it receives an array.
That's not valid Matlab code:
The % indicates the start of a comment, hence introducing a syntax error.
There is no append method (at least not for arrays).
Theres no need to increment the index in a for loop.
Aside of that it's a bad idea to have Matlab "grow" variables, as memory needs to be reallocated at each time, slowing it down considerably. The correct approach is:
variable=zeros(N,1);
for i=1:N
variable(i)=mod(i,2);
end
If you really do want to grow variables (some times it is inevitable) you can use this:
variable=[variable;1];
Use ; for appending rows, use , for appending columns (does the same as vertcat and horzcat). Use cat if you have more than 2 dimensions in your array.