loop through cell arrays and perform calculations using rows from another cell array

I am trying to do some calculations on some data which are stored in cell arrays but I cannot work around it.
I have a 1xm cell array named (DATA) which consists of kxn tables and a second cell array 1xm consisting of 1xn tables named (To).
I want to loop through the first cell array and perform the following equation on each row of each column of K and return a new cell array.
new_data = (Data - To)/To;
I am doing the following but no luck.
for j = 1:size (Data,2)
file = Data {1,j};
A_Data= table2array(file(:,2:31));
[NEW_TABLE{j}]= ((A_Data(1,j) - (To(1,j))./(To(1,j));
end

4 Comments

Attach Data and To in a .mat file
save('answers.mat', 'Data', 'To');
Use the paperclip icon.
Also explain why you're using a cell array for NEW_TABLE instead of just a regular double array. Also, enclosing NEW_TABLE in square brackets is unnecessary.
Attach a .mat file containing a couple elements of DATA and To...we can't infer what's what inside without being able to see. In general, it's highly unlikely you need table2array
@Image Analyst No particular reason for cell on new data. Attached the data.
@dpb attached the file. Some of the cells have a timestamp on the first column that's why i was initially converting.
@dpd the number of columns is just a mismatch you are right, just a mistake. I have made it work for data without timestamp and same number of columns but some of my data files have an added column with timestamp the first column. and this is when it does not work

Sign in to comment.

Answers (1)

DATA={table(rand(4,3))}; DATA(2,1)={table(rand(4,3))};
To={table(randi(5,4,1))}; To(2,1)={table(randi(5,4,1))};
% preliminaries of some sample data to work on out of the way, ...
% the engine
N=cellfun(@(d,t) (d{:,:}-t{:,:})./t{:,:},DATA,To,'UniformOutput',false);
yields
>> N{1}
ans =
-0.8177 -0.8075 -0.8770
-0.8086 -0.7553 -0.9355
-0.8487 -0.9777 -0.9926
-0.1567 -0.6039 -0.0256
>> DATA{1}
ans =
4×1 table
Var1
_______________________________
0.72902 0.77016 0.49206
0.76565 0.97866 0.25809
0.75658 0.11136 0.036966
0.84327 0.39608 0.97438
>> (DATA{1}.Var1-To{1}.Var1)./To{1}.Var1
ans =
-0.8177 -0.8075 -0.8770
-0.8086 -0.7553 -0.9355
-0.8487 -0.9777 -0.9926
-0.1567 -0.6039 -0.0256
>>
one could wrap N into a table if really wanted...
Also NB: that the anonymous function could have used .Var1 notation as well instead of {} syntax; the latter works whether is on variable as an array or a set of variables as columns...
NB2: The missing "." in the element-wise division using "./" is at least one source of your problem altho I didn't try to read the code itself for accuracy otherwise.

4 Comments

N=cellfun(@(d,t) (d{:,:}-t{:,:})./t{:,:},DATA,To,'UniformOutput',false);
"Unable to concatenate the table variables because their types are cell and double."
Tried this one and it won't work for files were the tables include timestamps.
Also I am not sure how to make this work as my data have different variable names and I want to apply the calc on each column of each table. I have multiple DATA cells and each table within it has at least 25 variables in some cases.
(DATA{1}.Var1-To{1}.Var1)./To{1}.Var1
>> baseline(1)
ans =
1×1 cell array
{1×5 table}
>> data(1)
ans =
1×1 cell array
{26×4 table}
>>
You said "... which consists of kxn tables and ... of 1xn tables"
Your data don't follow the above-stated rule--the baseline table has 5 variables while the data table has only four.
>> baseline{1}
ans =
1×5 table
CH0_1 CH0_2 CH0_3 CH0_4 CH0_5
______ ______ _____ _____ ______
1512.1 1516.8 1521 1525 1528.9
>>
and none of those look like a timestamp; just a mismatch in number of variables.
Fixing the data fixes the problem...
>> baseline{1}.CH0_5=[];
>> baseline{1}
ans =
1×4 table
CH0_1 CH0_2 CH0_3 CH0_4
______ ______ _____ _____
1512.1 1516.8 1521 1525
>> cellfun(@(d,t) (d{:,:}-t{:,:})./t{:,:},data(1),baseline(1),'UniformOutput',false)
ans =
1×1 cell array
{26×4 double}
>>
Operator error...
ADDENDUM:
One could write code to find the intersection of the variables between the two by name from the Properties.VariableNames cell arrays and operate only over those -- but it may/may not match in size depending upon what the two tables contain -- in this case, one could get all of the data table and throw away the extraneous T column, if the names don't match 1:1, there could be anything from that to the null set.
In 23a tables and timetables support standard arithmetic operations so in the cellfun call above you would no longer need the brace indexing (d{:,:}). It can be simplified to something like below.
DATA = {table(rand(4,3))}; DATA(2,1)={table(rand(4,3))};
To = {table(randi(5,4,1))}; To(2,1)={table(randi(5,4,1))};
N = cellfun(@(d,t) (d-t)./t, DATA, To, UniformOutput=false)
N = 2×1 cell array
{4×1 table} {4×1 table}
N{1}
ans = 4×1 table
Var1 ________________________________ -0.83098 -0.99589 -0.87143 -0.93153 -0.5457 -0.70528 -0.9316 -0.22232 -0.6871 -0.92957 -0.98464 -0.79505
It will also keep the output as a table.

Sign in to comment.

Products

Release

R2020b

Asked:

on 8 Mar 2021

Commented:

on 30 Mar 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!