MATLAB Answers

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

10 views (last 30 days)
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"];
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)'
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!


Sign in to comment.

Accepted Answer

Stephen Cobeldick
Stephen Cobeldick on 16 Jul 2019
Edited: Stephen Cobeldick on 16 Jul 2019
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 =
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:


Erika Puiutta
Erika Puiutta on 16 Jul 2019
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
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?
Stephen Cobeldick
Stephen Cobeldick on 16 Jul 2019
"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.

More Answers (0)