Hello everyone,
I have a .dat file like in the picture and I would like to modify I3 values (the last column). I can't use textscan since the beginning of the file has a different format.
Do you have any idea on how can I do this ?

댓글 수: 3

Rik
Rik 2020년 9월 3일
There are many methods to read files besides textscan. A simple google search should have turned up several.
What release are you using? Do you want to write the modified data exactly as it is in the original file? Then it might make the most sense to read as text and modify the char array directly.
Izem
Izem 2020년 9월 3일
Thank you sir for your answer !
I am using Matlab 2019b. Yeah I want to keep everything exactely the same except the last column where I want to replace the values by (old values+Delta(m,n)) .
How can I get the char array ?
Izem
Izem 2020년 9월 3일
Sorry for my stupid question. I am new to Matlab.
I think you mean :
C = fileread('text.dat');
Then I can modify those values. Thanks again.

댓글을 달려면 로그인하십시오.

 채택된 답변

Rik
Rik 2020년 9월 3일

1 개 추천

You can get my readfile function from the FEX or through the AddOn-manager (R2017a or later).
data=readfile(filename);
HeaderLines=9;
delta=rand(numel(data)-HeaderLines,1);%generate some random data for this example
for n=(HeaderLines+1):numel(data)
%store in temp variable
str=data{n};
%read the value, add something to it, and merge back
ind=strfind(str,' ');ind=ind(end)+1;%assumes you don't have a trailing space and the delimiter is a space
lastval=str2double(str(ind:end));
lastval=lastval+delta(n-HeaderLines);
str=sprintf('%s%.3f',str(1:(ind-1)),lastval);
%store back to array
data{n}=str;
end
%write back to file (overwrites the original)
fid=fopen(filename,'wt');
fprintf(fid,'%s\n',data{:});
fclose(fid)

댓글 수: 17

Izem
Izem 2020년 9월 8일
Hello, I have many errors.
-readfile does not exist
-'str=data{n};' I can't store data in this type of variable
-Problems with indices
Please find attached the text file
Rik
Rik 2020년 9월 8일
Which release are you using?
If you are using R2017a or later you will see an 'Add-Ons' button in the lint if click on the 'HOME' tab. If you click on it you will see a window with a search box. Type readfile and hit enter. My submission should be one of the top results. Click on it (the name or the icon; both will work). Now will see the button 'Add from GitHub'. Once you click it and wait a few seconds you will see a green banner over the icon saying 'Installed'. That means you can use the function.
If you have R2016b or earlier you will have to get it manually. Go to the link I provided in my answer. There you can click the button 'Download from GitHub'. That will download a zip file. Somewhere in that zip file you will find readfile.m. Put that file in your current folder, or put it somewhere on you path (e.g. create a folder C:\FEX-submissions\ put readfile.m there and run addpath('C:\FEX-sumissions\','-end');).
Tell me which one of the two options you tried and what if anything went wrong when getting readfile. You can use the second option for newer releases as well if you prefer.
Izem
Izem 2020년 9월 8일
I got the readfile function. Here is the error I have now :
'Array indices must be positive integers or logical values.'
Izem
Izem 2020년 9월 8일
I copied only the readfile.m in y folder. It s enough right ?
Rik
Rik 2020년 9월 8일
Your file has a trailing empty line. Put the code below at the start of the loop:
if isempty(data{n}),continue,end
Izem
Izem 2020년 9월 8일
Finally, it works. Thank you sir!
Izem
Izem 2020년 9월 8일
Sorry to bother you again I have another problem here.
Actually for the same m and n, The correction is the same so the size of my correction list is inferior than the number of lines in the text file (without headerlines). For example, as you can see in the picture, the first 5 lines that start with m = 0 and n = 1 have only one corresponding correction that should be added to all the five values in the last column of the text file.
I ve tried to convert the data{n} to num and then compare the two first values but when I go back to str after the modification, i don't find exactely the same format (there is a lot of spaces) Do you have any idea on how I can do this ?
Rik
Rik 2020년 9월 8일
How did you try to determine the values of m and n on a single line? That is your goal. Don't modify anything elso on the line, make a copy if you need to. Also note that m has values of 0, so those aren't valid Matlab indices.
Izem
Izem 2020년 9월 8일
I think you didn't get my request. Actually, what I asked for in the beggining was not what I wanted, your solution works perfect according to what I asked at the beggining. But now, I want to modify the alogithm so that for the same m and n, the addes value to the last column is the same like for example :
for m = 0 and n = 1
I3
96,84+val1
91.04+val1
89.75+val1
84.36+val1
83.96+val1
Rik
Rik 2020년 9월 8일
I did understand you. You just need to find a way to extract the values of m and n from a single line and use those to find the value you want to add. So how did you try to find m and n? Are m and n guaranteed to be single digit integers? That would make it a lot easier, although you could also just use textscan on the single lines by this point.
Izem
Izem 2020년 9월 8일
Ah I see. Wel, I Tried str2num to access m and n and then compare with the table where I have val1,val2..
m and n are integers between 0 and 100, would that makes it easy ? you think textscan is the way to go ?
Rik
Rik 2020년 9월 8일
Who taught you str2num? All the way back to at least R2011a you can read the advice to choose str2double instead. I don't think there is only one way to go, but str2num is certainly a worse choice than textscan.
What release are you using?
Izem
Izem 2020년 9월 8일
I m bginner in Matlab so I knew cell2mat and I tried to do the same with num and str. I am using 2019b.
Rik
Rik 2020년 9월 8일
You should really read the documentation. It is one of the major benefits of Matlab. As for this specific problem: you can easily get the values for m and n:
data=readfile('https://www.mathworks.com/matlabcentral/answers/uploaded_files/357712/Matlab.txt');
str=data{10};%select the first line to show the example
vals=textscan(str,' %f %f %f %f %f %f %f');
m=vals{1};n=vals{2};
Izem
Izem 2020년 9월 9일
Here is what I did and it worked well but is there any bad programming there ?
for i=(HeaderLines+1):numel(data)
%store in temp variable
if isempty(data{i}),continue,end
str=data{i};
vals=textscan(str,' %f %f %f %f %f %f %f');
m=vals{1}; n=vals{2};
for j=1:length(correction)
if m == str2double(mcorrection(j)) && n == str2double(ncorrection(j))
%read the value, add something to it, and merge back
ind=strfind(str,' ');ind=ind(end)+1;%assumes you don't have a trailing space and the delimiter is a space
lastval=str2double(str(ind:end));
lastval=lastval+correction(j);
str=sprintf('%s%.3f',str(1:(ind-1)),lastval);
%store back to array
data{i}=str;
end
end
end
%write back to file (overwrites the original)
fid=fopen(newname,'wt');
fprintf(fid,'%s\n',data{:});
fclose(fid);
Rik
Rik 2020년 9월 9일
I would separate finding the value of the correction and using it. I also would not use i and j as variables. You might also consider using ismember and/or find. A possible optimization would be to convert the mcorrection and ncorrection arrays to double only once (so outside the loop).
So no, I don't see any 'bad programming' here.
Izem
Izem 2020년 9월 9일
Alright! thank you sir for your help, I do appreciate it !

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Data Type Conversion에 대해 자세히 알아보기

제품

릴리스

R2019b

태그

질문:

2020년 9월 3일

댓글:

2020년 9월 9일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by