How can i change file within a loop?

%two snippets of code
----------------------------------------------------------------
gauge.source='PSMSL';
gauge.data(1).location='Vlissingen'; gauge.data(1).id='20';
gauge.data(2).location='Hoek van Holland'; gauge.data(2).id='22';
gauge.data(3).location='Roompot Buiten'; gauge.data(3).id='470';
gauge.data(4).location='Zeebrugge'; gauge.data(4).id='1551';
-----------------------------------------------------
%snippet 2
---------------------------------------------------------
filename = 'psmsl_monthly_20.txt';
% Open the file and read all lines to determine the number of lines
fileID = fopen(filename, 'r');
v = textscan(fileID, '%s%*[^\n]');
fclose(fileID);
------------------------------------------------------
So far everything runs But i want to change the filename voor more datat to read Ihav tried with numstring but I cannor figure out what I do wrong. Now my code runs but de data from Vlissingen are used for the other stations to. (ID 20)
How can i replace the code
filename = 'psmsl_monthly_20.txt';
to something like filename = 'psmsl_monthly_ "next station id".txt'; and let thecode read all the files.
Ellen

 Accepted Answer

I think you are looking for something like this
for k = 1:12
filename = ['psmsl_monthly_',num2str(k),'.txt']
% do something with filename, etc.
end
filename = 'psmsl_monthly_1.txt'
filename = 'psmsl_monthly_2.txt'
filename = 'psmsl_monthly_3.txt'
filename = 'psmsl_monthly_4.txt'
filename = 'psmsl_monthly_5.txt'
filename = 'psmsl_monthly_6.txt'
filename = 'psmsl_monthly_7.txt'
filename = 'psmsl_monthly_8.txt'
filename = 'psmsl_monthly_9.txt'
filename = 'psmsl_monthly_10.txt'
filename = 'psmsl_monthly_11.txt'
filename = 'psmsl_monthly_12.txt'

11 Comments

Or if you have leading zeros, for example, psmsl_monthly_08.txt, you can use
for k = 1:12
filename = ['psmsl_monthly_',num2str(k,'%02.f'),'.txt']
% do something with filename, etc.
end
filename = 'psmsl_monthly_01.txt'
filename = 'psmsl_monthly_02.txt'
filename = 'psmsl_monthly_03.txt'
filename = 'psmsl_monthly_04.txt'
filename = 'psmsl_monthly_05.txt'
filename = 'psmsl_monthly_06.txt'
filename = 'psmsl_monthly_07.txt'
filename = 'psmsl_monthly_08.txt'
filename = 'psmsl_monthly_09.txt'
filename = 'psmsl_monthly_10.txt'
filename = 'psmsl_monthly_11.txt'
filename = 'psmsl_monthly_12.txt'
Ellen
Ellen on 20 Feb 2024
Moved: Voss on 20 Feb 2024
Ive already defined de 4 stations with the number
gauge.source='PSMSL';
gauge.data(1).location='Vlissingen'; gauge.data(1).id='20';
gauge.data(2).location='Hoek van Holland'; gauge.data(2).id='22';
gauge.data(3).location='Roompot Buiten'; gauge.data(3).id='470';
gauge.data(4).location='Zeebrugge'; gauge.data(4).id='1551';
should I use 1,2,3 and 4 for k (k = station)
for stat=1:4
filename = ['psmsl_monthly_', num2str(gauge.data(stat).id), '.txt'];
it seems to work
Ellen
Jon
Jon on 20 Feb 2024
Moved: Voss on 20 Feb 2024
Yes it makes sense that if you have defined an array of station id's in your case, 20, 22, 470, 1551 corresponding to different locations, then you can index through those in your loop, e.g. stat = 1:4, obtain the corresponding station id, e.g. guage.data(stat).id, and then convert that to a string to get the corresponding file name for that station.
By the way, If this was just a follow up question on my answer, you could put it in as a comment rather than a new answer. Otherwise it's also ok to post your own solution as an alternative answer, but maybe not so easy for someone to follow the flow of the thread if that wasn't what you intended.
gauge.source='PSMSL';
gauge.data(1).location='Vlissingen'; gauge.data(1).id='20';
gauge.data(2).location='Hoek van Holland'; gauge.data(2).id='22';
gauge.data(3).location='Roompot Buiten'; gauge.data(3).id='470';
gauge.data(4).location='Zeebrugge'; gauge.data(4).id='1551';
There is no need for num2str in this case because the ids are already character vectors:
for stat = 1:numel(gauge.data)
filename = ['psmsl_monthly_', gauge.data(stat).id, '.txt'];
disp(filename);
end
psmsl_monthly_20.txt psmsl_monthly_22.txt psmsl_monthly_470.txt psmsl_monthly_1551.txt
You could also construct all the file names at once before the loop:
filenames = strcat('psmsl_monthly_',{gauge.data.id},'.txt');
for stat = 1:numel(gauge.data)
filename = filenames{stat};
disp(filename);
end
psmsl_monthly_20.txt psmsl_monthly_22.txt psmsl_monthly_470.txt psmsl_monthly_1551.txt
Jon
Jon on 20 Feb 2024
Edited: Jon on 20 Feb 2024
Hi @Voss, good catch that in the OP's example the ID numbers were already strings and wouldn't need to be converted. I hadn't noticed that and just assumed they would be numerical values.
I'm not sure if this was really what was intended though, or whether that would be a good idea. In general it seems better to me to keep numerical values as numbers and not strings unless there is a really good reason not to.
You helped a lot already but now I get NaN in de matrix
Il attach the code I am working with (and where i may have put some wrong brackets or so)
the psmsl_kopie.mat is what i try tot get from my code using different stations and a much newer mathlab version
I cannot include dat files so here te txt file from the student.--dat which is used for the statistics.
underneath a small part of a psmsl_monthly wile with 3 years of data. there are only diffrences in the second colums of the for files
this is what I get.
this is what the mat file should look like
but not NaN in the 1x27 double
0 0.10 0.05 0.025 0.1 0.005 0.001
1.0 3.078 6.314 12.706 31.821 63.657 318.313
2.0 1.886 2.920 4.303 6.965 9.925 22.327
3.0 1.638 2.353 3.182 4.541 5.841 10.215
4.0 1.533 2.132 2.776 3.747 4.604 7.173
5.0 1.476 2.015 2.571 3.365 4.032 5.893
6.0 1.440 1.943 2.447 3.143 3.707 5.208
7.0 1.415 1.895 2.365 2.998 3.499 4.782
8.0 1.397 1.860 2.306 2.896 3.355 4.499
9.0 1.383 1.833 2.262 2.821 3.250 4.296
10.0 1.372 1.812 2.228 2.764 3.169 4.143
11.0 1.363 1.796 2.201 2.718 3.106 4.024
12.0 1.356 1.782 2.179 2.681 3.055 3.929
13.0 1.350 1.771 2.160 2.650 3.012 3.852
14.0 1.345 1.761 2.145 2.624 2.977 3.787
15.0 1.341 1.753 2.131 2.602 2.947 3.733
16.0 1.337 1.746 2.120 2.583 2.921 3.686
17.0 1.333 1.740 2.110 2.567 2.898 3.646
18.0 1.330 1.734 2.101 2.552 2.878 3.610
19.0 1.328 1.729 2.093 2.539 2.861 3.579
20.0 1.325 1.725 2.086 2.528 2.845 3.552
21.0 1.323 1.721 2.080 2.518 2.831 3.527
22.0 1.321 1.717 2.074 2.508 2.819 3.505
23.0 1.319 1.714 2.069 2.500 2.807 3.485
24.0 1.318 1.711 2.064 2.492 2.797 3.467
25.0 1.316 1.708 2.060 2.485 2.787 3.450
26.0 1.315 1.706 2.056 2.479 2.779 3.435
27.0 1.314 1.703 2.052 2.473 2.771 3.421
28.0 1.313 1.701 2.048 2.467 2.763 3.408
29.0 1.311 1.699 2.045 2.462 2.756 3.396
30.0 1.310 1.697 2.042 2.457 2.750 3.385
31.0 1.309 1.696 2.040 2.453 2.744 3.375
32.0 1.309 1.694 2.037 2.449 2.738 3.365
33.0 1.308 1.692 2.035 2.445 2.733 3.356
34.0 1.307 1.691 2.032 2.441 2.728 3.348
35.0 1.306 1.690 2.030 2.438 2.724 3.340
36.0 1.306 1.688 2.028 2.434 2.719 3.333
37.0 1.305 1.687 2.026 2.431 2.715 3.326
38.0 1.304 1.686 2.024 2.429 2.712 3.319
39.0 1.304 1.685 2.023 2.426 2.708 3.313
40.0 1.303 1.684 2.021 2.423 2.704 3.307
41.0 1.303 1.683 2.020 2.421 2.701 3.301
42.0 1.302 1.682 2.018 2.418 2.698 3.296
43.0 1.302 1.681 2.017 2.416 2.695 3.291
44.0 1.301 1.680 2.015 2.414 2.692 3.286
45.0 1.301 1.679 2.014 2.412 2.690 3.281
46.0 1.300 1.679 2.013 2.410 2.687 3.277
47.0 1.300 1.678 2.012 2.408 2.685 3.273
48.0 1.299 1.677 2.011 2.407 2.682 3.269
49.0 1.299 1.677 2.010 2.405 2.680 3.265
50.0 1.299 1.676 2.009 2.403 2.678 3.261
51.0 1.298 1.675 2.008 2.402 2.676 3.258
52.0 1.298 1.675 2.007 2.400 2.674 3.255
53.0 1.298 1.674 2.006 2.399 2.672 3.251
54.0 1.297 1.674 2.005 2.397 2.670 3.248
55.0 1.297 1.673 2.004 2.396 2.668 3.245
56.0 1.297 1.673 2.003 2.395 2.667 3.242
57.0 1.297 1.672 2.002 2.394 2.665 3.239
58.0 1.296 1.672 2.002 2.392 2.663 3.237
59.0 1.296 1.671 2.001 2.391 2.662 3.234
60.0 1.296 1.671 2.000 2.390 2.660 3.232
61.0 1.296 1.670 2.000 2.389 2.659 3.229
62.0 1.295 1.670 1.999 2.388 2.657 3.227
63.0 1.295 1.669 1.998 2.387 2.656 3.225
64.0 1.295 1.669 1.998 2.386 2.655 3.223
65.0 1.295 1.669 1.997 2.385 2.654 3.220
66.0 1.295 1.668 1.997 2.384 2.652 3.218
67.0 1.294 1.668 1.996 2.383 2.651 3.216
68.0 1.294 1.668 1.995 2.382 2.650 3.214
69.0 1.294 1.667 1.995 2.382 2.649 3.213
70.0 1.294 1.667 1.994 2.381 2.648 3.211
71.0 1.294 1.667 1.994 2.380 2.647 3.209
72.0 1.293 1.666 1.993 2.379 2.646 3.207
73.0 1.293 1.666 1.993 2.379 2.645 3.206
74.0 1.293 1.666 1.993 2.378 2.644 3.204
75.0 1.293 1.665 1.992 2.377 2.643 3.202
76.0 1.293 1.665 1.992 2.376 2.642 3.201
77.0 1.293 1.665 1.991 2.376 2.641 3.199
78.0 1.292 1.665 1.991 2.375 2.640 3.198
79.0 1.292 1.664 1.990 2.374 2.640 3.197
80.0 1.292 1.664 1.990 2.374 2.639 3.195
81.0 1.292 1.664 1.990 2.373 2.638 3.194
82.0 1.292 1.664 1.989 2.373 2.637 3.193
83.0 1.292 1.663 1.989 2.372 2.636 3.191
84.0 1.292 1.663 1.989 2.372 2.636 3.190
85.0 1.292 1.663 1.988 2.371 2.635 3.189
86.0 1.291 1.663 1.988 2.370 2.634 3.188
87.0 1.291 1.663 1.988 2.370 2.634 3.187
88.0 1.291 1.662 1.987 2.369 2.633 3.185
89.0 1.291 1.662 1.987 2.369 2.632 3.184
90.0 1.291 1.662 1.987 2.368 2.632 3.183
91.0 1.291 1.662 1.986 2.368 2.631 3.182
92.0 1.291 1.662 1.986 2.368 2.630 3.181
93.0 1.291 1.661 1.986 2.367 2.630 3.180
94.0 1.291 1.661 1.986 2.367 2.629 3.179
95.0 1.291 1.661 1.985 2.366 2.629 3.178
96.0 1.290 1.661 1.985 2.366 2.628 3.177
97.0 1.290 1.661 1.985 2.365 2.627 3.176
98.0 1.290 1.661 1.984 2.365 2.627 3.175
99.0 1.290 1.660 1.984 2.365 2.626 3.175
100.0 1.290 1.660 1.984 2.364 2.626 3.174
the first three year of station 20
1996.0417 6699 0 000
1996.1250 6765 0 000
1996.2083 6677 0 000
1996.2917 6753 0 000
1996.3750 6837 0 000
1996.4583 6828 0 000
1996.5417 6859 0 000
1996.6250 6905 0 000
1996.7083 6852 0 000
1996.7917 6922 0 000
1996.8750 7053 0 000
1996.9583 6796 0 000
1997.0417 6746 0 000
1997.1250 6919 0 000
1997.2083 6827 0 000
1997.2917 6791 0 000
1997.3750 6810 0 000
1997.4583 6897 0 000
1997.5417 6825 0 000
1997.6250 6874 0 000
1997.7083 6894 0 000
1997.7917 6987 0 000
1997.8750 6879 0 000
1997.9583 6909 0 000
1998.0417 6962 0 000
1998.1250 6910 0 000
1998.2083 6830 0 000
1998.2917 6931 0 000
1998.3750 6825 0 000
1998.4583 6879 0 000
1998.5417 6963 0 000
1998.6250 6915 0 000
1998.7083 6989 0 000
1998.7917 7111 0 000
1998.8750 6925 0 000
1998.9583 6931 0 000
Your script, read_gauges2.m, trys to read the file, student_t_value.dat at line 9. You did not attach the file, student_t_value.dat, so I can not run your code to try to replicate/debug your errors. If you need more help with this, you will need to provide a script and any necessary files needed to replicate the problem.
Also, if this is now a new issue, that is it has nothing to do with the generation of the filenames to be read, then perhaps you should, submit this as a new question. When you do so, please, take some time to identify, exactly what your new question is, and provide an appropriate, self contained (not needed to refer back to this thread) description of the problem and any necessary files to reproduce the problem.
Ellen
Ellen on 22 Feb 2024
Moved: Stephen23 on 22 Feb 2024
I cannot add a dat-file but Ive put the data from the file underthe text I wrote. its that statistical thing with t values. You only need it for the rest of the data not for the part to construct the psmsl.mat. Ive run the file only this sector and saved the workspace.
I is in fact the data from this table:
By commenting out the initial lines of read_guages2 and loading your workspace_student_t_valuesector.mat I was able to reproduce your error.
Stepping through the code with the debugger, I see that the problem is here
for jj=startyear:endyear % go through separate years
% annual:
ind_yr=find(year==jj); % select entries with year jj
gauge.data(stat).annual_level(jj-startyear+1)=mean(level(ind_yr));
If you look at your values at this point, your variable, year, is an integer between 0 and 100, and you are trying to match it with a value of jj which is a value like 1999. So no match is found and ind_yr is empty. Then on the next line you take the mean of level(ind_yr), but since ind_yr is empty, so is level(ind_yr), and taking the mean of an empty value give NaN. So all of your levels are NaN.
So then later when you compute correlations your correlation coefficients are also NaN, and finally when you try to use the index N_eff -2, N_eff is also NaN, and so N_eff-2 is NaN and you get the error.
t_alf=t_0025(N_eff-2);
So you need to clean up the earlier part of your code
% read all entries
date=alldata(:,1); % in decimal years
year=floor(date);
month=ceil((date-floor(date))*12);
level=alldata(:,2); % in mm
Noting that, at least in the data you gave me, alldata(:,1) is not the date in decimal years, but is in fact just integer values from 0 to 100
nd_yr=find(year==jj); % select entries with year jj
gauge.data(stat).annual_level(jj-startyear+1)=mean(level(ind_yr));
you mean I have tot change jj (above txt) to jjjj?
nd_yr=find(year==jjjj); % select entries with year jj
gauge.data(stat).annual_level(jjjj-startyear+1)=mean(level(ind_yr));
Ellen
Jon
Jon on 27 Feb 2024
Edited: Jon on 27 Feb 2024
I think you are getting confused about working with character vectors, e.g. '1996' and numerical values, 1996.
I'm not totally clear on what you are suggesting here, but it somehow looks like you are thinking that you should compare to jjjj rather than jj to get more digits. If so, then this is not what I meant at all.
Here is the situation.
You first assign a numerical values, (not a character vectors or strings) to your variables date and year, on the lines where you have
date=alldata(:,1); % in decimal years
year=floor(date);
If you look at the values for alldata(:,1), the column you are assigning to date, it is a vector of numerical values (not characters or strings) whose elements are 0, 1, 2, .... 100.
As they do not have any decimal fraction, taking the floor of them leaves them unchanged, so your variable year, is a vector of numerical values (not characters or strings) whose elements are 0,1,2,...100
Next you have a loop in which you assign the loop variable jj, to take on numerical values (not strings or characters) from startyear to endyear which you assigned earlier using
% select years:
startyear=1996;
%startyear=1995; % for plot
endyear=2022;
so as you loop jj wil take on the numerical values 1996,1997,1998,...2022
Inside of the loop you look for the ind_yr (index into the vector of numerical year values) using
ind_yr=find(year==jj); % select entries with year jj
so you are looking for the element of year where year has a value that matches jj.
Since the elements of year have values, 0,1,2,...101 and, lets say on the first loop, jj = 1996, it clearly will not find any match, there is no element of year that has the value 1996, so it returns empty.
Next you try to compute the mean value of the level corresponding to the ind_yr with right hand side of the line
gauge.data(stat).annual_level(jj-startyear+1)=mean(level(ind_yr));
Since ind_yr is empty, level(ind_yr) is also empty. Since MATLAB doesn't know how to compute the mean of an empty vector, it simple return NaN (which means not a number), and NaN is assigned to
gauge.data(stat).annual_level(jj-startyear+1)
This continues with each successive loop, on the next loop jj =1997, which also is not found in year, which only has value 0,1,2,...101. and again the ind_yr is empty the mean level is NaN until finally all of the values of guage.data(stat).annual_level have been assigned NaN
After that there are no useful results, as you try to compute correlations etc from these vectors of NaN and obviously it can't compute anything useful just using NaN's, and eventually you actually have an error.
So you need to either get your year values to be in the range 1996 to 2022, perhaps by adding your variable called date to some base year. Alternatively you leave the year values as 0,1,2,... and modify the condition you check for a match, so if the year values were, for example, the number of years after 1990, then you could check for
ind_yr = find(year == jj - 1990)
so when, for example jj = 1999, it would give ind_yr = 10, since year(10) has a value of 9 (your year values start at zero) and 1999-1990 equals 9
I hope this helps.

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2023b

Asked:

on 20 Feb 2024

Edited:

Jon
on 27 Feb 2024

Community Treasure Hunt

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

Start Hunting!