 |
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
Srabon
Joined: 22 Feb 2011 Posts: 14
|
Posted: Tue Feb 22, 2011 5:12 pm Post subject: How to count data frequency and assign to bins |
|
|
I happened to find the following problem in Chapman and currently working on it. But not sure how to code the data sorting part and assign them to the right bin.
Can anybody give me tips toward the solution?
Cheers! |
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Tue Feb 22, 2011 8:06 pm Post subject: |
|
|
if score is an integer, then use the following snippet. Note that in the graph, the last bin has 6 possible scores whereas the others have 5.
Code: |
integer :: score, bin, histogram(1:7)
...
! Initialise histogram
histogram = 0
...
! loop over scores goes here
! Assign score to bin
if (score >= 65 .and. score < 100) then
! Integer division to get bin number
bin = (score - 65)/5 + 1
else if (score == 100) then
bin = 7
end if
! Update histogram (bar chart)
histogram(bin) = histogram(bin) + 1
|
Presumably no one can get more than 100. You need to think about what to do about students who get 64 or less. |
|
Back to top |
|
 |
Srabon
Joined: 22 Feb 2011 Posts: 14
|
Posted: Tue Feb 22, 2011 9:59 pm Post subject: |
|
|
Thanks for your direction, David.
In light of the OP, I tried to devise the following example, in which 100 scores (from 1-100) are read from an external file and assigned to 10 bins using the intrinsic function to get the minimum and maximum scores. The program of course did not work. Any modification therefore would be greatly appreciated. Thanks a bunch!
Code: | program chapman
integer :: bin,score,min,max,histogram(1:10),fail
fail=0
!open files to read and write
open (unit=10,file='score.txt')
open (unit=11,file='binning.txt')
!read score from file
read(10,*,iostat=fail) score
!get minimum and maximum scores
min = minval(score)
max = maxval(score)
!Initialise histogram
histogram = 0
!loop over scores goes here
!Assign score to bin
do i=1,100,1
if (score >= min .and. score < max) then
!Integer division to get bin number
bin = (score - min)/(max-min)
else if (score => 100) then
bin = 10
else if (score =< 0) then
bin = 1
end if
!Update histogram (bar chart)
histogram(bin) = histogram(bin) + 1
enddo
!To get bin vs frequncy count and write to output files
write(11,*) bin,histogram
end
|
|
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Wed Feb 23, 2011 12:02 am Post subject: |
|
|
try the following, which should progress your solution
Code: | program chapman
integer :: bin, score(1000),mins,maxs, histogram(0:11),fail ,i,n, bin_step
fail=0
!open files to read and write
open (unit=10,file='score.txt')
open (unit=11,file='binning.txt')
!read all score values from file
do i = 1,size(score)
read (10,*,iostat=fail) score(i)
if (fail /=0) exit
end do
n = i-1
!get minimum and maximum scores
mins = max (minval (score(1:n)), 0)
maxs = min (maxval (score(1:n)),100)
bin_step = (maxs-mins)/10
!Initialise histogram
histogram = 0
!loop over scores goes here
!Assign score to bin
do i=1,n
!! if (score(i) >= mins .and. score(i) < maxs) then ! why this test ?
!Integer division to get bin number
bin = (score(i) - mins) / bin_step + 1
!!else if (score(i) => 100) then
if (bin >10) bin = 11
!!else if (score(i) =< 0) then
if (bin < 1) bin = 0
!!end if
!Update histogram (bar chart)
histogram(bin) = histogram(bin) + 1
end do
!To get bin vs frequncy count and write to output files
write (11,*) 'Number of scores', n
write (11,*) 'Min score', mins
write (11,*) 'Max score', maxs
write (11,*) 'Bin step', bin_step
write (11,*) 'Bin values'
do bin = 0,11
i = (bin-1) * bin_step + mins
write (11,*) bin, i, histogram(bin)
end do
end
|
|
|
Back to top |
|
 |
Srabon
Joined: 22 Feb 2011 Posts: 14
|
Posted: Wed Feb 23, 2011 3:58 pm Post subject: |
|
|
@John, thank you for your kind help.
To check my understanding of the code, I tried to modify (with no success),
1. to suit for any score files that contain any score, negative or positive.
2. For multiple score files and their comparison, normalizing the histograms
Could anybody suggest the mistakes?
Thanks again for the correction in advance.
Code: |
program chapman_anynumber
integer :: histogram(1:100),fail ,i,n, bin_num,count
real::score(1000),mins,maxs,bin_scale
fail=0
bin_num=10
open (unit=10,file='anynum.txt')
open (unit=11,file='anynum.dat')
!read all score values from file
do i = 1,size(score)
read (10,*,iostat=fail) score(i)
if (fail /=0) exit
end do
n = i-1
!Initialise histogram
histogram = 0
mins = minval (score(1:n))
maxs = maxval (score(1:n))
!loop over scores goes here
!Assign score to bin
do i=1,n
holder = (score(i) - mins)*( real(bin_num)/ (maxs-mins))
if (holder>bin_num) holder = bin_num-1
!converting holder from real to integer
count=int(holder) + 1
!update histogram
histogram(count) = histogram(count) + 1
end do
write (11,*) '#Number of scores', n
write (11,*) '#Min score', mins
write (11,*) '#Max score', maxs
!write (11,*) '#Bin step', bin_step
write (11,*) '#Bin values'
!normalizing histogram for different score files comparison
do i = 0,bin_num
histogram(i)=histogram(i)/(n/REAL(bin_num))
bin_scale = mins+((i-1)*maxs/real(bin_num))
write (11,*) bin_num, bin_scale, histogram(bin_num)
enddo
end |
|
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Thu Feb 24, 2011 1:09 am Post subject: |
|
|
I changed your code again,
calculated % in each bin
reported the number of scores retrieved to the screen (good to know as it runs)
COUNT = 0 is a possibility so HISTOGRAM should be declared (0:10)
you should use the do loop counter"i", rather than "bin_num" when refering to values in the loop.
Note the difference between the intrinsic INT and NINT when calculating "COUNT"
Your use of "HOLDER" has some problems. It's also better to apply the test on range of COUNT, which is integer.
Code: | program chapman_anynumber
integer :: histogram(0:100),fail ,i,n, bin_num, count ! change range
real :: score(1000),mins,maxs, bin_scale, bin_min,bin_avg, percent
!
! fail=0 not needed
bin_num=10 ! it could be up to 100 ?
open (unit=10,file='anynum.txt')
open (unit=11,file='anynum.dat')
!read all score values from file
do i = 1,size(score)
read (10,*,iostat=fail) score(i)
if (fail /= 0) exit
end do
n = i-1
write (*,*) n, ' scores recovered from file ', 'anynum.txt'
! if comparing files, do you want a new range for each file ?
mins = minval (score(1:n))
maxs = maxval (score(1:n))
bin_scale = (maxs-mins) / real(bin_num) ! range of each bin
!
!Assign score to bin
!
histogram = 0 ! Initialise histogram count
do i=1,n
count = int ( (score(i) - mins) / bin_scale ) ! use INT or NINT to convert
if (count < 0) count = 0
if (count > bin_num) count = bin_num
histogram(count) = histogram(count) + 1
end do
write (11,*) '#Number of scores', n
write (11,*) '#Min score', mins
write (11,*) '#Max score', maxs
write (11,*) '#Average score', sum(score(1:n)) / real(n)
!write (11,*) '#Bin step', bin_scale
write (11,*) '#Bin values'
!normalizing histogram for different score files comparison
do i = 0, ubound (histogram,1)
if (histogram(i) == 0) cycle
!
bin_min = mins + real(i) * bin_scale ! if INT used above
bin_avg = mins + (real(i)+0.5) * bin_scale ! if INT used above
percent = real(histogram(i)) / real(n) * 100.
write ( *,1001) i, bin_avg, histogram(i), percent
write (11,1001) i, bin_avg, histogram(i), percent
end do
1001 format (i5,f7.1, i6, f7.1,'%')
end |
|
|
Back to top |
|
 |
Srabon
Joined: 22 Feb 2011 Posts: 14
|
Posted: Thu Feb 24, 2011 10:59 pm Post subject: |
|
|
Thank you so much, John! I really appreciate your great cooperation! |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|