How can I get and write data from text file?

조회 수: 1 (최근 30일)
Suat YAZICI
Suat YAZICI 2019년 3월 19일
편집: Stephen23 2019년 3월 22일
Text file as follows:
  • A column: Year (1998:1:2017)
  • B column: Day of the year (1:1:365 or 366)
  • C column: Hour
1998 152 1 30 25 12.5
1998 152 1 30 30 12
1998 152 1 30 35 11.8
1998 152 1 30 40 11.9
1998 152 1 30 45 12
I would like to get data but I have problem for leap year of 366 days. I'd like to extract all rows and then write data to text file, which is D= 30 and E=25 and B>=152 and B<=243 but it changes B>=153 and B<=244 according to leap years. I tried something but I got 0 and 1. How can I write text file what I want?
load fulltable.txt;
yearlenght = 365+(eomday(fulltable(:,1),2) == 29);
if fulltable(:,1) == yearlenght;
test = fulltable(fulltable(:,2)>=153 & fulltable(:,2)<=244 & fulltable(:,4)==30 & fulltable(:,5)==25,:);
else fulltable(:,1) ~= yearlenght;
test = fulltable(fulltable(:,2)>=152 & fulltable(:,2)<=243 & fulltable(:,4)==30 & fulltable(:,5)==25,:);
end
  댓글 수: 8
Stephen23
Stephen23 2019년 3월 22일
편집: Stephen23 2019년 3월 22일
'...because the test is only for the first value of 'a'. And this is likely the root of your problem: you're testing for a vector, but 'if' only checks the first value.'
This is incorrect. Nowhere in the MATLAB documention does it mention anything about "first value" being checked by the IF operator. In fact the IF documentation clearly states "An expression is true when its result is nonempty and contains only nonzero elements (logical or real numeric). Otherwise, the expression is false". Note that it states that all elements must be non-zero for the IF condition to be considered true, not just the first one as Martin Brorsen incorrectly claims.
Here is a simple test which shows that Martin Brorsen's explanation is incorrect, and that the MATLAB documenation correctly describes how MATLAB behaves
>> if [1,0,0], disp('only first'), else disp('wrong!'), end
wrong!
>> if [1,2,3], disp('all elements'), else disp('wrong!'), end
all elements
'"if" tests on either 0 or positive. '
This is incorrect. In fact the MATLAB documentation makes it clear that it tests for nonzero value (which can be positive or negative). This is easy to confirm:
>> if -1, disp('nonzero'), end
nonzero
To know how the IF operator works, read the IF documentation:
Martin Brorsen
Martin Brorsen 2019년 3월 22일
Okay, my mistake. But my comment still stands in regards to the above question. Please stay on track when answering questions.
(and there's really no need to repeatedly edit your answer, it's just spamming activity feed)

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

채택된 답변

Stephen23
Stephen23 2019년 3월 22일
편집: Stephen23 2019년 3월 22일
This code sorts the file data into one cell array C, where each cell in C contains the summer data for one year. The summer start and end dates are adjusted for the leap years.
mat = dlmread('fulltable.txt');
ily = (mod(mat(:,1),4)==0&mod(mat(:,1),100))|~mod(mat(:,1),400); % leap year.
idx = mat(:,2)>=(152+ily) & mat(:,2)<=(243+ily); % summer start and end dates.
idr = find(idx);
idg = cumsum([true;diff(idr)~=1]); % years into group numbers.
idz = find(mat(:,4)==30 & mat(:,5)==25); % match D and E column data.
fun = @(r){mat(intersect(r,idz),:)};
C = accumarray(idg,idr,[],fun);
And checking the start and end dates by looking at the first and last few rows of some of the cells:
>> C{1}(1:4,:)
ans =
1998 152 1 30 25 12.5
1998 152 3 30 25 10.9
1998 152 5 30 25 9.6
1998 152 7 30 25 8.4
>> C{1}(end-3:end,:)
ans =
1998 243 17 30 25 34.6
1998 243 19 30 25 32.5
1998 243 21 30 25 29.4
1998 243 23 30 25 20.5
>> C{3}(1:4,:)
ans =
2000 153 1 30 25 29.6
2000 153 3 30 25 25.4
2000 153 5 30 25 20.8
2000 153 7 30 25 15.7
>> C{3}(end-3:end,:)
ans =
2000 244 17 30 25 44.3
2000 244 19 30 25 44.8
2000 244 21 30 25 37.4
2000 244 23 30 25 29.5
You can then simply loop over the cells of the that cell array and export the data in files. Read the documentation to know how to access data in a cell array and save sequential files:

추가 답변 (1개)

Suat YAZICI
Suat YAZICI 2019년 3월 22일
Thank you to everyone for explanation. I did it finally.
load data.txt;
[row col] = size(data);
test=[];
format short
fileID=fopen('result.txt','w');
for i=1:row
if mod(data(i,1),4) == 0 && data(i,2)>=153 && data(i,2)<=244 && data(i,4)==30 && data(i,5)==25
test=[test; data(i,:)];
fprintf(fileID,'%d %d %d %2.1f %2.1f %3.1f \n',data(i,:));
else if mod(data(i,1),4) ~= 0 && data(i,2)>=152 && data(i,2)<=243 && data(i,4)==30 && data(i,5)==25
test=[test; data(i,:)];
fprintf(fileID,'%d %d %d %2.1f %2.1f %3.1f \n',data(i,:));
end
end
end
fclose(fileID)
  댓글 수: 1
Stephen23
Stephen23 2019년 3월 22일
편집: Stephen23 2019년 3월 22일
You can easily avoid the loop using logical indices (see my answer), which gives simpler, much more efficient code (with the same output file):
fmt = '%d %d %d %2.1f %2.1f %3.1f\n';
mat = dlmread('fulltable.txt');
ily = (mod(mat(:,1),4)==0&mod(mat(:,1),100))|~mod(mat(:,1),400);
idx = mat(:,2)>=(152+ily) & mat(:,2)<=(243+ily);
idz = mat(:,4)==30 & mat(:,5)==25;
fid = fopen('fulltable_2.txt','wt');
fprintf(fid,fmt,mat(idx&idz,:).');
fclose(fid);
Compared:
Elapsed time is 3.059008 seconds. % your answer
Elapsed time is 0.044557 seconds. % my code

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

카테고리

Help CenterFile Exchange에서 Logical에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by