Resample function with splitapply limitation?

I'm working with a drilling datset.
The rate of penetration 'rop' is acquired non-uniformly and recorded as a depth (in meters). Depth and rop are doubles. I have the hole names as categories.
I've been able to uniformly resample one hole's rop and depth at the the desired depth spacing (0.1m).
e.g. hole12's first meter using function [y,ty] = resample(yg,t,fs);
t = original depth
yg = original rop
y = resampled rop
ty = resampled depth
fs = frequency resampled
holeid = [12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12];
depth = [0;0.0542;0.0801;0.2222;0.3959;0.4572;0.5110;0.5348;0.5712;0.6099;0.6437;0.6799;0.8011;0.8928;0.9590;1.0110];
rop = [118.7000;207.8000;139.6000;176.0000;177.8000;229.3000;242.4000;138.9000;85.7000;140.8000;164.5000;125.4000;189.8000;164.0000;118.4000;211.4000];
hole12 = table(holeid,depth,rop)
hole12 = 16×3 table
holeid depth rop ______ ______ _____ 12 0 118.7 12 0.0542 207.8 12 0.0801 139.6 12 0.2222 176 12 0.3959 177.8 12 0.4572 229.3 12 0.511 242.4 12 0.5348 138.9 12 0.5712 85.7 12 0.6099 140.8 12 0.6437 164.5 12 0.6799 125.4 12 0.8011 189.8 12 0.8928 164 12 0.959 118.4 12 1.011 211.4
fs = 10;
[y,yt] = func(hole12.rop,hole12.depth,fs)
y = 11×1
112.9171 169.2608 165.6799 174.9927 194.6960 194.1402 118.9197 152.2125 178.4882 163.0119
yt = 11×1
0 0.1000 0.2000 0.3000 0.4000 0.5000 0.6000 0.7000 0.8000 0.9000
y = 11×1
112.9171 169.2608 165.6799 174.9927 194.6960 194.1402 118.9197 152.2125 178.4882 163.0119
yt = 11×1
0 0.1000 0.2000 0.3000 0.4000 0.5000 0.6000 0.7000 0.8000 0.9000
plot(hole12.rop,hole12.depth);
hold on
plot(y,yt);
hold off
legend({'original','resampled'})
xlabel('rop')
ylabel('depth')
set(gca, 'YDir','reverse')
Unfortunately, it doesn't seem to work for multiple holes when using the resample function and splitapply to apply the function to each group i.e. hole to yield a uniformly resampled depth and 'rop'.
holeid = [12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13];
depth = [0;0.0542;0.0801;0.2222;0.3959;0.4572;0.5110;0.5348;0.5712;0.6099;0.6437;0.6799;0.8011;0.8928;0.9590;1.0110;0;0.0432;0.1334;0.2483;0.4087;0.4443;0.5009;0.5567;0.5890;0.6253;0.6923;0.7274;0.7588;0.8296;0.8623;0.8955;0.9272;0.9652;0.9959;1.0218];
rop = [118.7000;207.8000;139.6000;176.0000;177.8000;229.3000;242.4000;138.9000;85.7000;140.8000;164.5000;125.4000;189.8000;164.0000;118.4000;211.4000;148.8000;227.9000;14.6000;220.1000;177.2000;226.0000;144.5000;114.2000;157.8000;207.8000;242.5000;247.5000;238.7000;245.7000;241.4000;244.7000;235.6000;242.7000;239.1000;226.0000];
holes12and13 = table(holeid,depth,rop)
holes12and13 = 36×3 table
holeid depth rop ______ ______ _____ 12 0 118.7 12 0.0542 207.8 12 0.0801 139.6 12 0.2222 176 12 0.3959 177.8 12 0.4572 229.3 12 0.511 242.4 12 0.5348 138.9 12 0.5712 85.7 12 0.6099 140.8 12 0.6437 164.5 12 0.6799 125.4 12 0.8011 189.8 12 0.8928 164 12 0.959 118.4 12 1.011 211.4
holes12and13.holeid = categorical(holes12and13.holeid)
holes12and13 = 36×3 table
holeid depth rop ______ ______ _____ 12 0 118.7 12 0.0542 207.8 12 0.0801 139.6 12 0.2222 176 12 0.3959 177.8 12 0.4572 229.3 12 0.511 242.4 12 0.5348 138.9 12 0.5712 85.7 12 0.6099 140.8 12 0.6437 164.5 12 0.6799 125.4 12 0.8011 189.8 12 0.8928 164 12 0.959 118.4 12 1.011 211.4
G = findgroups(holes12and13.holeid)
G = 36×1
1 1 1 1 1 1 1 1 1 1
[y1,ty1] = splitapply(func,holes12and13.rop,holes12and13.depth,fs,holes12and13.rop,G)
Not enough input arguments.

Error in solution>func (line 26)
[y,yt] = resample(yg,t,fs)
function [y,yt] = func(yg,t,fs);
[y,yt] = resample(yg,t,fs)
end
Is this a syntax issue calling the function inputs or a limitation of splitapply because it can only apply the function to one input at a time (e.g. 'x') (instead of the three required for the resample function work e.g. 'yg','t' and 'fs')? Is there another way to accomplish this e.g. a loop and how would that be done based on groupds of categorical data?

 Réponse acceptée

Your fundamental problem was that you were calling splitapply(func, ...) which causes the function func to be evaluated with no inputs, and the expectation that func() will return a function handle that will be passed into splitapply(). You need to pass in @func to use func as the function handle to pass to split apply.
But you have other problems. You do not define fs . Presumably it is a scalar. But splitapply() requires that all of the parameters have the same number of rows as it splits all of them .
If you use
splitapply(@func,holes12and13.rop,holes12and13.depth,fs,holes12and13.rop,G)
then you are telling splitapply() that @func expects 4 inputs -- the rop, the depth, the fs, and the rop again, as four independent parameters. But your func only accepts three inputs.
holeid = [12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13];
depth = [0;0.0542;0.0801;0.2222;0.3959;0.4572;0.5110;0.5348;0.5712;0.6099;0.6437;0.6799;0.8011;0.8928;0.9590;1.0110;0;0.0432;0.1334;0.2483;0.4087;0.4443;0.5009;0.5567;0.5890;0.6253;0.6923;0.7274;0.7588;0.8296;0.8623;0.8955;0.9272;0.9652;0.9959;1.0218];
rop = [118.7000;207.8000;139.6000;176.0000;177.8000;229.3000;242.4000;138.9000;85.7000;140.8000;164.5000;125.4000;189.8000;164.0000;118.4000;211.4000;148.8000;227.9000;14.6000;220.1000;177.2000;226.0000;144.5000;114.2000;157.8000;207.8000;242.5000;247.5000;238.7000;245.7000;241.4000;244.7000;235.6000;242.7000;239.1000;226.0000];
holes12and13 = table(holeid,depth,rop)
holes12and13 = 36×3 table
holeid depth rop ______ ______ _____ 12 0 118.7 12 0.0542 207.8 12 0.0801 139.6 12 0.2222 176 12 0.3959 177.8 12 0.4572 229.3 12 0.511 242.4 12 0.5348 138.9 12 0.5712 85.7 12 0.6099 140.8 12 0.6437 164.5 12 0.6799 125.4 12 0.8011 189.8 12 0.8928 164 12 0.959 118.4 12 1.011 211.4
holes12and13.holeid = categorical(holes12and13.holeid)
holes12and13 = 36×3 table
holeid depth rop ______ ______ _____ 12 0 118.7 12 0.0542 207.8 12 0.0801 139.6 12 0.2222 176 12 0.3959 177.8 12 0.4572 229.3 12 0.511 242.4 12 0.5348 138.9 12 0.5712 85.7 12 0.6099 140.8 12 0.6437 164.5 12 0.6799 125.4 12 0.8011 189.8 12 0.8928 164 12 0.959 118.4 12 1.011 211.4
G = findgroups(holes12and13.holeid)
G = 36×1
1 1 1 1 1 1 1 1 1 1
fs = 8000;
[y1,ty1] = splitapply(@func,holes12and13.rop,holes12and13.depth,fs,holes12and13.rop,G)
Error using splitapply (line 99)
The data variables must have the same number of rows as the vector of group numbers. The group number vector has 36 row(s), and data variable 3 has 1 row(s).
function [y,yt] = func(yg,t,fs);
whos
which resample
nargin
[y,yt] = resample(yg,t,fs)
end

8 commentaires

Thank you for pointing me in the right direction about reading and identifying those problems.
I have removed the second instance of holes12and13.rop so only the three inputs remain (yg,t,fs).
I've implemented your corrections and added a column of 'fs' values to the holes12and13 table to get around the row number issue for splitapply but now am getting another error.
holeid = [12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13];
depth = [0;0.0542;0.0801;0.2222;0.3959;0.4572;0.5110;0.5348;0.5712;0.6099;0.6437;0.6799;0.8011;0.8928;0.9590;1.0110;0;0.0432;0.1334;0.2483;0.4087;0.4443;0.5009;0.5567;0.5890;0.6253;0.6923;0.7274;0.7588;0.8296;0.8623;0.8955;0.9272;0.9652;0.9959;1.0218];
rop = [118.7000;207.8000;139.6000;176.0000;177.8000;229.3000;242.4000;138.9000;85.7000;140.8000;164.5000;125.4000;189.8000;164.0000;118.4000;211.4000;148.8000;227.9000;14.6000;220.1000;177.2000;226.0000;144.5000;114.2000;157.8000;207.8000;242.5000;247.5000;238.7000;245.7000;241.4000;244.7000;235.6000;242.7000;239.1000;226.0000];
holes12and13 = table(holeid,depth,rop)
holes12and13 = 36×3 table
holeid depth rop ______ ______ _____ 12 0 118.7 12 0.0542 207.8 12 0.0801 139.6 12 0.2222 176 12 0.3959 177.8 12 0.4572 229.3 12 0.511 242.4 12 0.5348 138.9 12 0.5712 85.7 12 0.6099 140.8 12 0.6437 164.5 12 0.6799 125.4 12 0.8011 189.8 12 0.8928 164 12 0.959 118.4 12 1.011 211.4
holes12and13.Properties.VariableNames{1} = 'holeid';
holes12and13.Var4(1,1) = 10;
holes12and13.Properties.VariableNames{4} = 'fs';
G = findgroups(holes12and13.holeid)
G = 36×1
1 1 1 1 1 1 1 1 1 1
[y1,ty1] = splitapply(@func,holes12and13.rop,holes12and13.depth,holes12and13.fs,G)
Name Size Bytes Class Attributes fs 16x1 128 double t 16x1 128 double yg 16x1 128 double /MATLAB/toolbox/signal/signal/resample.m
ans = 3
Error using splitapply (line 132)
Applying the function 'func' to the 1st group of data generated the following error:

Expected input number 3, Fs, to be a scalar.
function [y,yt] = func(yg,t,fs);
whos
which resample
nargin
[y,yt] = resample(yg,t,fs)
end
My understanding is fs is meant to be scalar in the resample function, whereas splitarray requires the same number of rows.
Is there a method to account for this incompatibility with splitarray and resample when using the 'fs' method to resample non-uniformly collected samples?
[y1,ty1] = splitapply(@(r,d)func(r,d,fs), holes12and13.rop, holes12and13.depth,G)
to resample non-uniformly collected samples?
?? Are you saying that fs is not constant? The way you set fs in your table implies that your first fs is 10 and the rest are zero ??
Thanks for identifying that error. I've fixed up the column fs_non_scalar to be a constant 10.
In the code above, how does adding (r,d) change the function definition at the end?
e.g. [y1,ty1] = splitapply(@(r,d)func(r,d,fs), holes12and13.rop, holes12and13.depth,G)
holeid = [12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13];
depth = [0;0.0542;0.0801;0.2222;0.3959;0.4572;0.5110;0.5348;0.5712;0.6099;0.6437;0.6799;0.8011;0.8928;0.9590;1.0110;0;0.0432;0.1334;0.2483;0.4087;0.4443;0.5009;0.5567;0.5890;0.6253;0.6923;0.7274;0.7588;0.8296;0.8623;0.8955;0.9272;0.9652;0.9959;1.0218];
rop = [118.7000;207.8000;139.6000;176.0000;177.8000;229.3000;242.4000;138.9000;85.7000;140.8000;164.5000;125.4000;189.8000;164.0000;118.4000;211.4000;148.8000;227.9000;14.6000;220.1000;177.2000;226.0000;144.5000;114.2000;157.8000;207.8000;242.5000;247.5000;238.7000;245.7000;241.4000;244.7000;235.6000;242.7000;239.1000;226.0000];
fs_non_scalar = [10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10];
holes12and13 = table(holeid,depth,rop,fs_non_scalar)
holes12and13 = 36×4 table
holeid depth rop fs_non_scalar ______ ______ _____ _____________ 12 0 118.7 10 12 0.0542 207.8 10 12 0.0801 139.6 10 12 0.2222 176 10 12 0.3959 177.8 10 12 0.4572 229.3 10 12 0.511 242.4 10 12 0.5348 138.9 10 12 0.5712 85.7 10 12 0.6099 140.8 10 12 0.6437 164.5 10 12 0.6799 125.4 10 12 0.8011 189.8 10 12 0.8928 164 10 12 0.959 118.4 10 12 1.011 211.4 10
fs = 10;
G = findgroups(holes12and13.holeid);
[y1,ty1] = splitapply(@func,holes12and13.rop,holes12and13.depth,holes12and13.fs_non_scalar,G)
Name Size Bytes Class Attributes fs 16x1 128 double t 16x1 128 double yg 16x1 128 double /MATLAB/toolbox/signal/signal/resample.m
ans = 3
Error using splitapply (line 132)
Applying the function 'func' to the 1st group of data generated the following error:

Expected input number 3, Fs, to be a scalar.
function [y,yt] = func(yg,t,fs);
whos
which resample
nargin
[y,yt] = resample(yg,t,fs)
end
Hi Walter. Applying the anonymous function code you've suggested leads to an undefined function error.
How can I avoid this?
holeid = [12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13];
depth = [0;0.0542;0.0801;0.2222;0.3959;0.4572;0.5110;0.5348;0.5712;0.6099;0.6437;0.6799;0.8011;0.8928;0.9590;1.0110;0;0.0432;0.1334;0.2483;0.4087;0.4443;0.5009;0.5567;0.5890;0.6253;0.6923;0.7274;0.7588;0.8296;0.8623;0.8955;0.9272;0.9652;0.9959;1.0218];
rop = [118.7000;207.8000;139.6000;176.0000;177.8000;229.3000;242.4000;138.9000;85.7000;140.8000;164.5000;125.4000;189.8000;164.0000;118.4000;211.4000;148.8000;227.9000;14.6000;220.1000;177.2000;226.0000;144.5000;114.2000;157.8000;207.8000;242.5000;247.5000;238.7000;245.7000;241.4000;244.7000;235.6000;242.7000;239.1000;226.0000];
fs_non_scalar = [10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10];
holes12and13 = table(holeid,depth,rop,fs_non_scalar);
fs = 10;
G = findgroups(holes12and13.holeid);
[y1,ty1] = splitapply(@(r,d)func(r,d,fs), holes12and13.rop, holes12and13.depth,G)
Error using splitapply (line 132)
Applying the function '@(r,d)func(r,d,fs)' to the 1st group of data generated the following error:

Undefined function 'func' for input arguments of type 'double'.
you still need the definition for func that you have been posting
function [y,yt] = func(yg,t,fs);
whos
which resample
nargin
[y,yt] = resample(yg,t,fs)
end
Hi Walter. I'm still getting an error when using the 'splitapply(@(r,d)func(r,d,fs)' function you've suggested with the function handle definition. Thanks for all your help so far. It's very frustrating for me being new to MATLAB...
holeid = [12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13];
depth = [0;0.0542;0.0801;0.2222;0.3959;0.4572;0.5110;0.5348;0.5712;0.6099;0.6437;0.6799;0.8011;0.8928;0.9590;1.0110;0;0.0432;0.1334;0.2483;0.4087;0.4443;0.5009;0.5567;0.5890;0.6253;0.6923;0.7274;0.7588;0.8296;0.8623;0.8955;0.9272;0.9652;0.9959;1.0218];
rop = [118.7000;207.8000;139.6000;176.0000;177.8000;229.3000;242.4000;138.9000;85.7000;140.8000;164.5000;125.4000;189.8000;164.0000;118.4000;211.4000;148.8000;227.9000;14.6000;220.1000;177.2000;226.0000;144.5000;114.2000;157.8000;207.8000;242.5000;247.5000;238.7000;245.7000;241.4000;244.7000;235.6000;242.7000;239.1000;226.0000];
fs10 = [10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10];
holes12and13 = table(holeid,depth,rop,fs10);
fs = 10;
G = findgroups(holes12and13.holeid);
[y1,ty1] = splitapply(@(r,d)func(r,d,fs), holes12and13.rop, holes12and13.depth,G);
Name Size Bytes Class Attributes fs 1x1 8 double t 16x1 128 double yg 16x1 128 double /MATLAB/toolbox/signal/signal/resample.m
ans = 3
y = 11×1
112.9171 169.2608 165.6799 174.9927 194.6960 194.1402 118.9197 152.2125 178.4882 163.0119
yt = 11×1
0 0.1000 0.2000 0.3000 0.4000 0.5000 0.6000 0.7000 0.8000 0.9000
Error using splitapply (line 132)
The function '@(r,d)func(r,d,fs)' returned a non-scalar value when applied to the 1st group of data.

To compute nonscalar values for each group, create an anonymous function to return each value in a scalar cell:

@(r,d){func(r,d,fs)}
function [y,yt] = func(yg,t,fs);
whos
which resample
nargin
[y,yt] = resample(yg,t,fs)
end
holeid = [12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13];
depth = [0;0.0542;0.0801;0.2222;0.3959;0.4572;0.5110;0.5348;0.5712;0.6099;0.6437;0.6799;0.8011;0.8928;0.9590;1.0110;0;0.0432;0.1334;0.2483;0.4087;0.4443;0.5009;0.5567;0.5890;0.6253;0.6923;0.7274;0.7588;0.8296;0.8623;0.8955;0.9272;0.9652;0.9959;1.0218];
rop = [118.7000;207.8000;139.6000;176.0000;177.8000;229.3000;242.4000;138.9000;85.7000;140.8000;164.5000;125.4000;189.8000;164.0000;118.4000;211.4000;148.8000;227.9000;14.6000;220.1000;177.2000;226.0000;144.5000;114.2000;157.8000;207.8000;242.5000;247.5000;238.7000;245.7000;241.4000;244.7000;235.6000;242.7000;239.1000;226.0000];
fs10 = [10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10];
holes12and13 = table(holeid,depth,rop,fs10);
fs = 10;
G = findgroups(holes12and13.holeid);
[y1,ty1] = splitapply(@(r,d)func(r,d,fs), holes12and13.rop, holes12and13.depth,G);
y1, ty1
y1 = 2×1 cell array
{11×1 double} {11×1 double}
ty1 = 2×1 cell array
{11×1 double} {11×1 double}
function [y,yt] = func(yg,t,fs);
[ty,tyt] = resample(yg,t,fs);
y = {ty}; yt = {tyt};
end
Thank you!

Connectez-vous pour commenter.

Plus de réponses (0)

Produits

Version

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by