# convert string of numbers to double

11 views (last 30 days)
Joseph Sassoon on 19 Aug 2019
Edited: Stephen Cobeldick on 20 Aug 2019
I have timestamp data saved as follows:
% Stim=["676, 933, 1645, 2069:.025:2069.5, 2327:.025:2327.5, 2542:.05:2543";"3"];
where each row would represent a column that corresponds to the experiment it was from. (3 is just a test value). Here I store the timestamps as a string so that I can concatonate different sized elements.
I was hoping to use str2double to extract these timestamps but I get NaN returned when I try.
% Stim=str2double(Stim(1)) - would be doing this itteratively
Thanks!!

Show 1 older comment
TADA on 19 Aug 2019
is that supposed to be a vector?
x = 2069:.025:2069.5
1x21 double
if that is it, you can use str2num instead of str2double
take caution with str2num as it uses eval, so if you don't completely trust the source of the string, don't use str2num
Joseph Sassoon on 19 Aug 2019
The colons represent a vector, the dots decimals..
I ened up adding brackets inside of the strings so it now looks like this:
Stim=["[676, 933, 1645, 2069:.025:2069.5, 2327:.025:2327.5, 2542:.05:2543]";"[3]"];
I was then able to use str2sym to extract all the values
Thanks for your suggestion!!
Stephen Cobeldick on 19 Aug 2019

Stephen Cobeldick on 20 Aug 2019
Edited: Stephen Cobeldick on 20 Aug 2019
More efficient than converting to symbolic and probably also str2num:
>> S = '676, 933, 1645, 2069:.025:2069.5, 2327:.025:2327.5, 2542:.05:2543';
>> [V,~,~,X] = sscanf(S,'%f,%f,%f',[1,Inf])
V =
676 933 1645
X =
15
>> W = sscanf(S(X:end),',%f:%f:%f',[3,Inf])
W =
2069 2327 2542
0.025 0.025 0.05
2069.5 2327.5 2543
Use the colon operator on the columns of W to generate the required vectors. Whilst a well-designed loop (or simply writing the code three times) would be fastest and most efficient, with cellfun this can be more compact:
>> format bank
>> C = cellfun(@(w)w(1):w(2):w(3),num2cell(W,1),'uni',0);
>> C{:}
ans =
2069.00 2069.03 2069.05 2069.07 2069.10 2069.12 2069.15 2069.18 2069.20 2069.22 2069.25 2069.28 2069.30 2069.32 2069.35 2069.38 2069.40 2069.43 2069.45 2069.47 2069.50
ans =
2327.00 2327.03 2327.05 2327.07 2327.10 2327.12 2327.15 2327.18 2327.20 2327.22 2327.25 2327.28 2327.30 2327.32 2327.35 2327.38 2327.40 2327.43 2327.45 2327.47 2327.50
ans =
2542.00 2542.05 2542.10 2542.15 2542.20 2542.25 2542.30 2542.35 2542.40 2542.45 2542.50 2542.55 2542.60 2542.65 2542.70 2542.75 2542.80 2542.85 2542.90 2542.95 2543.00
And then the complete vector is easy:
>> Z = [V,C{:}];
>> numel(Z)
ans = 66

Joseph Sassoon on 20 Aug 2019
Thanks for the suggestion!
But I believe that your method does not produce all of the values listed in S. W gets the parameters for the vector, but in the end I would want to produce the 66 values described above. Is there a difference way you can accomplish this with your method?
Rik on 20 Aug 2019
This code gets you all 66 values:
S = '676, 933, 1645, 2069:.025:2069.5, 2327:.025:2327.5, 2542:.05:2543';
[V,~,~,X] = sscanf(S,'%f,%f,%f');
W = sscanf(S(X:end),',%f:%f:%f',[3,Inf]);
c = mat2cell(W,3,[1 1 1]);
out = cellfun(@(x) x(1):x(2):x(3),c,'UniformOutput',false);
out = cat(2,V',out{:});
I don't know if the overhead of mat2cell and cellfun is worth it, or if you should use a loop instead.