我有一个程序来读取和分层具有(x,y)值的多元正态总体的R文件。我想将人口分成两组,其中除法基于x和y是否高于或低于特定数字。
当我在Fortran中进行分层时,我得到的结果是x和y没有结果,就像这样
total number of individuals 1551
0.00000000 0.00000000
0.00000000 0.00000000
0.00000000 0.00000000
0.00000000 0.00000000
0.00000000 0.00000000
0.00000000 0.00000000
0.00000000 0.00000000
0.00000000 0.00000000
0.00000000 0.00000000
0.00000000 0.00000000
.
.
.
原始数据如下所示
755,885
656,841
742,844
747,829
776,861
696,809
782,891
771,867
760,826
812,830
711,792
736,840
738,873
793,833
751,836
747,871
796,830
711,868
747,843
758,835
760,824
759,839
696,868
I have attached the file to the original data from R as well
program test
implicit none
real, dimension(:), allocatable :: x,y
real, dimension(:,:), allocatable :: s1, s2, s3, s4
integer:: io, l1, l2, l3,l4,n,i
open(33, file = '', status = 'old', action = 'read')
n = 0
DO
READ(33,*,iostat=io)
IF (io/=0) EXIT
n = n + 1
END DO
allocate(x(n) ,y(n))
rewind(33)
DO i =1,n
READ(33,*) x(i), y(i)
END DO
allocate(s1(n,2))
allocate(s2(n,2))
allocate(s3(n,2))
allocate(s4(n,2))
s1=0
s2=0
s3=0
s4=0
l1=1
l2=1
l3=1
l4=1
do i = 1 , n
if (x(i) >=0 .AND. x(i)<=500) then
if( y(i) >= 0 .AND. y(i) <=500) then
s1(l1, :)=(/x(i), y(i) /)
l1=l1+1
end if
else if (x(i) > 500 .AND. x(i) <= 1000 ) then
if ( y(i) > 0 .AND. y(i) < 500 ) then
s2(l2, :)=(/x(i), y(i) /)
l2=l2+1
end if
end if
write(*,*) s1(l1, :)
end do !iloop
end program test
我不知道我在这做错了什么。
答案 0 :(得分:0)
这被称为&#34;悬空的ELSE问题&#34;。 FORTRAN认为&#34;否则if(x(i)&gt; 500 ...&#34;部分属于&#34; if(y(i)&gt; = 0 .AND.y(i) &lt; = 500)&#34;声明。在&#34; else&#34;之前添加&#34; END IF&#34;。
do i = 1 , n
if (x(i) >=0 .AND. x(i)<=500) THEN
if( y(i) >= 0 .AND. y(i) <=500) THEN
s1(l1, :)=(/x(i), y(i) /)
l1=l1+1
end if
else if (x(i) > 500 .AND. x(i) <= 1000 )THEN
if ( y(i) > 0 .AND. y(i) < 500 ) THEN
s2(l2, :)=(/x(i), y(i) /)
l2=l2+1
END IF
END IF
END do !iloop
答案 1 :(得分:0)
鉴于您提供的示例数据文件,我认为您获得的输出是正确的。每个案例属于x> 1。 500,y> 500,您的代码不适合将这些条目写入分层。
根据我的理解,以下是您原始问题的解决方案。我已将代码分解为许多子例程,这有助于使其更容易理解。请注意,我的代码中的假设是所有数据都在0 - 1000范围内。
module util
implicit none
private
public :: get_strat
public :: write_strat
contains
function get_strat(x, y) result(strat)
integer, intent(in) :: x
integer, intent(in) :: y
integer :: strat
integer, parameter :: mid_val = 500
if (x < mid_val .and. y < mid_val) then
strat = 1
else if (x < mid_val .and. y >= mid_val) then
strat = 2
else if (x > mid_val .and. y < mid_val) then
strat = 3
else
strat = 4
end if
end function
subroutine write_strat(trg, strat, x, y)
integer, intent(in) :: trg
integer, intent(in) :: strat(:)
integer, intent(in) :: x(:)
integer, intent(in) :: y(:)
integer :: i, count_strat
count_strat = 0
write(*, *) "Writing stratification ", trg
do i = 1, size(x)
if (strat(i) == trg) then
write(*, *) x(i), y(i)
count_strat = count_strat + 1
end if
end do
write(*, *) "Total = ", count_strat
write(*, *)
end subroutine
end module util
program test
use util
implicit none
integer, dimension(:), allocatable :: x,y, strat
integer:: io, n, i
open(33, file = 'xyBVNData_R.txt', status = 'old', action = 'read')
n = 0
do
read(33, *, iostat=io)
if( io /= 0) exit
n = n + 1
end do
allocate(x(n) ,y(n), strat(n))
rewind(33)
do i = 1, n
read(33, *) x(i), y(i)
end do
do i = 1, n
strat(i) = get_strat(x(i), y(i))
end do
do i = 1, 4
call write_strat(i, strat, x, y)
end do
end program test
通过分解这样的代码,可以更容易理解并发现任何逻辑缺陷。例如,在您的代码中,行计数变量l1
...在找到匹配后递增。这意味着在程序结束时,计数大于匹配条目的数量。更明确的习语是:
l# = 0
...
if (...logic...)
l# = l# + 1
!! Do something
end if