MATLAB Answers

0

How do I use sprintf with two variables with different sizes?

Asked by Erika Puiutta on 16 Jul 2019
Latest activity Edited by Stephen Cobeldick on 16 Jul 2019
Hello!
I am analysing MEG data and have 20 participants with 3 blocks (called '00', '10' and '23') each, so 20x3 datasets. I want to append all these datasets with a function.
In the function, I have to manually spell out ALL the datasets that I want to append. For example:
[appendeddata] = ft_appenddata(cfg, s(1).rawdata.data00, s(1).rawdata.data10, s(1).rawdata.data23, s(2).rawdata.data00,... %and so forth
So I would have to spell out all 60 combinations, so s(1:20) and block(00,10,23). I tried to get around this by using sprinft like this:
block=["00" "10" "23"];
Subj=strings(1,20);
Subj(1:20)=1:20;
sprintf('s(%s).rawdata.data%s,',Subj,block)
But this leads to this:
ans = 's(1).rawdata.data2,s(3).rawdata.data4,s(5).rawdata.data6,s(7).rawdata.data8,s(9).rawdata.data10,s(11).rawdata.data12,s(13).rawdata.data14,s(15).rawdata.data16,s(17).rawdata.data18,s(19).rawdata.data20,s(00).rawdata.data10,s(23).rawdata.data'
How can I tell sprintf to assign the values of the first variable "Subj" to the first instance of %s, and the values of the second variable "block" to the second instance? Is that possible at all?
Thanks in advance for any answers!

  0 Comments

Sign in to comment.

Tags

Products

1 Answer

Answer by Stephen Cobeldick on 16 Jul 2019
Edited by Stephen Cobeldick on 16 Jul 2019
 Accepted Answer

Assuming that you have nested structures, then you can easily do something like this:
>> s(1).rawdata.data00 = 100;
>> s(1).rawdata.data10 = 110;
>> s(1).rawdata.data23 = 123;
>> s(2).rawdata.data00 = 200;
>> s(2).rawdata.data10 = 210;
>> s(2).rawdata.data23 = 223;
>> F = @(t){t.rawdata.data00,t.rawdata.data10,t.rawdata.data23};
>> C = arrayfun(F,s,'uni',0);
>> C = [C{:}];
>> V = cat(1,C{:}) % your function here!
V =
100
110
123
200
210
223
This simple method uses two comma-separated lists:
For your function you would simply need to call:
ft_appenddata(cfg, C{:})
Note that your approach of using strings will lead you into writing slow, complex, buggy, obfuscated code that is hard to debug. You should always use MATLAB in terms of arrays and indices, not by trying to manipulate strings that only indirectly represent what you are trying to achieve:

  2 Comments

Thank you so much, it works ike a charm!
In my code, I have indeed written the strings in the variable name with indexed variables, for example:
instead of
s(1).rawdata.data00
I have
SubjNum = 1:20;
savenam = {'rawdata','tsss98'};
info.stim = {'00','10','23'};
block = 1:3;
s(SubjNum).([savenam{i}]).(['data' info.stim{block}])
Is that what you mean with using arrays and indices instead of strings?
"I have indeed written the strings in the variable name with indexed variables..."
The code you show uses dynamic fieldnames and indexing, but no "strings in the variable name" as you write. The variable is named s, and the variable name should not be accessed dynamically (and you don't in your example, so that is fine).
"Is that what you mean with using arrays and indices instead of strings?"
Yes. Contrast this with the code you show in your question, where you also define the variable name s in some strings... which then requires executing the string like code, which is exactly what should be avoided (as the last link in my answer explains).

Sign in to comment.