Splitapply: Returning multiple output values

7 views (last 30 days)
Hello everyone. I am currently stuck at a problem which refers to the application of the splitapply function for a function with multiple output values. More specifically, i am trying to get the correlation coefficient r, as well as the corresponding p-value for the subsets of multiple columns of a table, specified by group numbers. Here is an example:
A = array2table(rand(100,1));
A.Properties.VariableNames{1} = 'Row1';
A.Row2 = rand(100,1);
B = [1:1:10]';
A.Groups = repmat(B,10,1);
Given is a table A with 2 columns, containing 10 observations in chronological order for 10 different groups. The following formula returns the r coefficients i am looking for.
R = splitapply(@(a,b) {corrcoef(a,b)},A.Row1,A.Row2,A.Groups);
But the syntax for multiple outputvalues, [R,P] = corrcoef (a,b), does not work if i simply put it in front of the splitapply funcion as follows:
[R,P] = splitapply(@(a,b) {corrcoef(a,b)},A.Row1,A.Row2,A.Groups);
I guess i have to use a local function to recieve both of the values. Unfortunately i am not really experienced in using them, and after doing a little research, i have still absoluty no idea what to type. It would be a blessing if somebody could help me out.
Thank you very much for reading

Accepted Answer

dpb
dpb on 24 Jun 2021
Edited: dpb on 24 Jun 2021
This is harder because corrcoef returns a square maxtrix, not just the 2-sample coefficient, p-values.
Easiest is to write a helper function to do that part --
function [r,p]=mycorr(x,y)
% two-sample correlation, p values for x,y
[r,p]=corrcoef(x,y);
r=r(2,1);
p=p(2,1);
end
tA=table(rand(100,1),rand(100,1),'VariableNames',{'A','B'}); % sample data table
tA.G=fix([0:height(tA)-1]/10).'; % create grouping variable
% the engine
>> rowfun(@(a,b) (mycorr(a,b)),tA,"InputVariables",{'A','B'},'SeparateInputs',1,'NumOutputs',2,'GroupingVariables','G')
ans =
10×4 table
G GroupCount Var3 Var4
_ __________ _________ _______
0 10 0.19267 0.59383
1 10 0.39138 0.26338
2 10 0.13497 0.71007
3 10 -0.11946 0.74237
4 10 0.11982 0.74163
5 10 0.27951 0.43414
6 10 0.01039 0.97728
7 10 -0.087027 0.81106
8 10 -0.039839 0.91299
9 10 -0.078133 0.83012
>>
>> % Illustrate get same result for second group of 10
>> [r,p]=corrcoef(tA.A([1:10]+10),tA.B(10+[1:10]))
r =
1.0000 0.3914
0.3914 1.0000
p =
1.0000 0.2634
0.2634 1.0000
>>
  2 Comments
Maximilian Hauschel
Maximilian Hauschel on 25 Jun 2021
Didn't expect those fast replys. Seems like splitapply isn't the most suitable function to handle this case. But your answer really helps me out. Many thanks, dpb.
dpb
dpb on 25 Jun 2021
Guess all depends on what want for the output...the cell of redundant data or just the actual values without redundancy...

Sign in to comment.

More Answers (1)

Adam Danz
Adam Danz on 24 Jun 2021
Use arrayfun instead.
A = array2table(rand(100,1));
A.Properties.VariableNames{1} = 'Row1';
A.Row2 = rand(100,1);
B = [1:1:10]';
A.Groups = repmat(B,10,1);
[R,P] = arrayfun(@(i) corrcoef(A.Row1(A.Groups==i), A.Row2(A.Groups==i)), ...
unique(A.Groups), 'UniformOutput',false)
R = 10×1 cell array
{2×2 double} {2×2 double} {2×2 double} {2×2 double} {2×2 double} {2×2 double} {2×2 double} {2×2 double} {2×2 double} {2×2 double}
P = 10×1 cell array
{2×2 double} {2×2 double} {2×2 double} {2×2 double} {2×2 double} {2×2 double} {2×2 double} {2×2 double} {2×2 double} {2×2 double}
  1 Comment
Maximilian Hauschel
Maximilian Hauschel on 25 Jun 2021
That's an even more elegant solution. Never thought of applying arrayfun, because i've never had to use it anytime before. Looks like i should really get used to it. Also thank you for your fast and helpfull reply.

Sign in to comment.

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!