NetLogo: reading data from input files with variable numbers of lines
I've been running game theory simulations in NetLogo and I now have lots data files, containing cross-tabulated data - each column store a value of a different variable, and there are c. 1000 rows containing the data. I'm trying to write a programme that will take these files and calculate the mean value for each column.
I have a programme that works as long as there is a constant number of data rows in each file. The programme uses a loop of file-read commands to calculate running totals, which are then divided by the nuber of rows read once all of the rows have been read.
However, my real data files have variable numbers of rows. I have been trying to modify my code using file-at-end? to get it to exit the running total loop after the last line, but I haven't been able to find any way of employing it that works - I just get an error saying that the file is at an end.
Please could someone suggest a way of dealing with this? I've pasted the working code below.
--
globals [target-file-name
current-tally-file
lines-read
coops-fixed-run cheats-fixed-run either-fixed-run coop-freq-min-run
coop-freq-max-run coop-freq-mean-run ticks-run
num-lines
]
to setup
set target-file-name user-input "Type a name for the target file"
file-open target-file-name
file-print("TallyFile Reps pFixCoop pFixCheat pFixEither MeanMinCoop MeanMaxCoop MeanMeanCoop")
file-close
set num-lines read-from-string user-input "How many lines in the file to be processed?"
end
to go
set current-tally-file user-file
file-open current-tally-file
set lines-read 0
while [lines-read < num-lines][
let in1 file-read set coops-fixed-run (coops-fixed-run + in1)
let in2 file-read set cheats-fixed-run (cheats-fixed-run + in2)
let in3 file-read set either-fixed-run (either-fixed-run + in3)
let in4 file-read set coop-freq-min-run (coop-freq-min-run + in4)
let in5 file-read set coop-freq-max-run (coop-freq-max-run + in5)
let in6 file-read set coop-freq-mean-run (coop-freq-mean-run + in6)
let in7 file-read set ticks-run (ticks-run + in7)
set lines-read (lines-read + 1)
]
stop-and-clear
end
to stop-a开发者_开发问答nd-clear
let pfixcoop (coops-fixed-run / lines-read)
let pfixcheat (cheats-fixed-run / lines-read)
let pfixeither (either-fixed-run / lines-read)
let mean-of-mins (coop-freq-min-run / lines-read)
let mean-of-maxs (coop-freq-max-run / lines-read)
let mean-of-means (coop-freq-mean-run / lines-read)
let mean-of-ticks (ticks-run / lines-read)
file-open target-file-name
file-print (word current-tally-file " " lines-read " " pfixcoop " " pfixcheat "
" pfixeither " " mean-of-mins " " mean-of-maxs " " mean-of-means " "
mean-of-ticks)
file-close
set coops-fixed-run 0
set cheats-fixed-run 0
set either-fixed-run 0
set coop-freq-min-run 0
set coop-freq-max-run 0
set coop-freq-mean-run 0
set ticks-run 0
set lines-read 0
stop
end
A method to read all lines from a file looks like:
to read-file [filename]
file-open filename
while [not file-at-end?][
;read one line
let in1 file-read
let in2 file-read
;and so one, at the end you will probably want to put these into some global variable
set global-in1 fput in1 global-in1
]
file-close filename
end
This assumes that all rows have exactly the name number of data items, and you know what that number is. Otherwise just use file-read-line instead of file-read
精彩评论