Nicholas Hayden
Nicholas Hayden

Reputation: 523

How would you perform inter-row operations based on multiple columns? MATLAB

I am a novice programmer that is primarily self-taught. I am new to MATLAB and relational mathematics. Currently, I am attempting to perform math operations between rows. I would like to normalize the exp by the corresponding con and then multiply by the constant.

This constant is a laboratory measurement that could be subject to change in future experments. Thus, I have given it a column.

Below is some sample code that I have generated to exemplify my problem and solution. I am trying to get from myTable to rTable.

I recognize my solution is very sloppy and there must be a way to perform these operations that is human-readable and uses less temporary variables. To put it shortly, there must be a simpler way.

rTable = table();
myTable = table(transpose(1:8), ...
                transpose({'Con1', 'Con2', 'Exp1', 'Exp2',...
                           'Con1', 'Con2', 'Exp1', 'Exp2'}),...
                transpose({'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'}),...
                ones(8, 1) * 2,...
                'VariableNames', {'Values' , 'Condition', 'Group', 'Constant'});

[r, c] = size(myTable)

a = myTable(strcmp(myTable.Group, 'A'), :);
b = myTable(strcmp(myTable.Group, 'B'), :);

aexp1 = a.Values(strcmp(a.Condition, 'Exp1'), :) / a.Values(strcmp(a.Condition, 'Con1'), :) * mean(a.Constant);
aexp2 = a.Values(strcmp(a.Condition, 'Exp2'), :) / a.Values(strcmp(a.Condition, 'Con2'), :) * mean(a.Constant);

bexp1 = b.Values(strcmp(b.Condition, 'Exp1'), :) / b.Values(strcmp(b.Condition, 'Con1'), :) * mean(b.Constant);
bexp2 = b.Values(strcmp(b.Condition, 'Exp2'), :) / b.Values(strcmp(b.Condition, 'Con2'), :) * mean(b.Constant);

aT = table(transpose({aexp1, aexp2}),...
           transpose({'Exp1', 'Exp2'}),...
           transpose({'A', 'A'}),...
           transpose({2, 2,}),...
           'VariableNames', {'Values', 'Condition', 'Group', 'Constant'});

bT = table(transpose({bexp1, bexp2}),...
           transpose({'Exp1', 'Exp2'}),...
           transpose({'B', 'B'}),...
           transpose({2, 2,}),...
           'VariableNames', {'Values', 'Condition', 'Group', 'Constant'});

rTable = [aT; bT]

Thank you for any input or suggestions. Perhaps, the data structure i am handling is poorly organized.

Upvotes: 0

Views: 82

Answers (1)

liyuan
liyuan

Reputation: 553

Here's one solution:

rTable = table();
myTable = table((1:8)',{'Con1', 'Con2', 'Exp1', 'Exp2','Con1', 'Con2', 'Exp1', 'Exp2'}',...
    {'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'}','VariableNames', {'Values' , 'Condition', 'Group', 'Constant'})





conditionrows = contains(myTable.Condition,'Con')
exprows = contains(myTable.Condition,'Exp')
conditionTable = myTable(conditionrows,:)
expTable = myTable(exprows,:)

constant = 2
rValues = expTable.Values./conditionTable.Values * constant

rTable = expTable
rTable.Values = rValues

Since you are trying to get a table of only exprows, you separate your original table into a conditionTable and an expTable. I'm assuming you have one condition row for each exp row, and also that you have a good correspondence in the tables (if not it will require more processing), then you can calculate the rValue simply with a one line expression. The ./ is element-wise division. Also note that you can use ' to perform transpose in matlab (further note that if you want a column vector of 1:10 for example you have to do (1:10)', 1:10' gives you a row vector from 1 to 10 since 1:10' is interpreted as vector from 1 to the transpose of 10.

Upvotes: 1

Related Questions