281
edits
(array slice tips) |
|||
Line 4: | Line 4: | ||
=== Retrieve a field value from all entries in a struct array === | === Retrieve a field value from all entries in a struct array === | ||
==== Problem ==== | ==== Problem ==== | ||
You have a struct array with multiple fields, and you want to | You have a struct array with multiple fields, and you want to access the value from a specific field from all elements. For example, you want to return the age from all patients in the following case: | ||
samples = struct ("patient", {"Bob", "Kevin", "Bob" , "Andrew"}, | samples = struct ("patient", {"Bob", "Kevin", "Bob" , "Andrew"}, | ||
Line 30: | Line 30: | ||
[samples([samples(:).age] > 34).tube] ## return tube numbers from all samples from patients older than 34 | [samples([samples(:).age] > 34).tube] ## return tube numbers from all samples from patients older than 34 | ||
[samples(strcmp({samples(:).protein}, "CDK2")).tube] ## return all tube numbers for protein CDK2 | [samples(strcmp({samples(:).protein}, "CDK2")).tube] ## return all tube numbers for protein CDK2 | ||
== Array manipulation == | |||
=== Select a slice from an n-D array === | |||
==== Problem ==== | |||
For an array {{Codeline|A}} with arbitrary number of dimensions, select, for example, the first column. This would be {{Codeline|A(:, 1)}} if {{Codeline|A}} was 2-D, {{Codeline|A(:, 1, :)}} if {{Codeline|A}} was 3-D, and so on. | |||
==== Solution ==== | |||
One possibility is to use {{Codeline|subsref}} with the input {{Codeline|idx}} created dynamically with {{Codeline|repelems}} to have the right number of dimensions. This can be written as a function: | |||
{{Code||<syntaxhighlight lang="octave" style="font-size:13px"> | |||
function [B]= array_slice (A,k,d) | |||
#return the k-th slice (row, column...) of A, with d specifying the dimension to slice on | |||
idx.type = "()"; | |||
idx.subs = repelems ({':'}, [1;ndims(A)]); | |||
idx.subs(d) = k; | |||
B = subsref (A,idx); | |||
endfunction | |||
#test cases | |||
%!shared A | |||
%! A=rand(2, 3); | |||
%!assert (array_slice (A,1,2), A(:, 1)) | |||
%! A=rand(2, 3, 4); | |||
%!assert (array_slice (A,2,1), A(2, :, :)) | |||
%! A=rand(2, 3, 4, 5); | |||
%!assert (array_slice (A,1,2), A(:, 1, :, :)) | |||
%! A=rand(2, 3, 4, 5, 6); | |||
%!assert (array_slice (A,2,3), A(:, :, 2, :, :)) | |||
</syntaxhighlight>}} | |||
To remove the singleton dimension {{Codeline|d}} from the result {{Codeline|B}}, use | |||
{{Code||<syntaxhighlight lang="octave" style="font-size:13px"> | |||
B = reshape(B, [size(B)([1:d-1 d+1:end])]); | |||
</syntaxhighlight>}} | |||
== Input/output == | == Input/output == |
edits