MATLAB Answers

0

convert string of numbers to double

Asked by Joseph Sassoon on 19 Aug 2019 at 18:11
Latest activity Edited by Stephen Cobeldick on 20 Aug 2019 at 16:05
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!!

  4 Comments

Show 1 older comment
TADA
on 19 Aug 2019 at 18:35
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
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!!

Sign in to comment.

1 Answer

Answer by Stephen Cobeldick on 20 Aug 2019 at 10:33
Edited by Stephen Cobeldick on 20 Aug 2019 at 16:05

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

  2 Comments

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 at 15:16
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.

Sign in to comment.