我有两个 p*n 数组,y 和 ymiss。 y 包含实数和 NA。 ymiss 包含 1 和 0,因此如果 y(i,j)==NA,则 ymiss(i,j)==0,否则为 1。我还有 1*n 数组 ydim,它告诉 y(1:p,n) 有多少个实数,因此 ydim 的值为 0 到 p
在 R 编程语言中,我可以执行以下操作:
if(ydim!=p && ydim!=0)
y(1:ydim(t), t) = y(ymiss(,t), t)
该代码将 y(,t) 的所有实数排列成这样
首先有一个例子 y(,t) = (3,1,NA,6,2,NA) 代码之后是 y(,t) = (3,1,6,2,2,NA)
现在我只需要前一个 1:ydim(t),所以其余的是什么并不重要。
问题是,我怎样才能在 Fortran 中做类似的事情?
谢谢
朱尼
最佳答案
“where 语句”和“merge”内部函数功能强大,可在数组中的选定位置上进行操作,但它们不会将项目移动到数组的前面。使用具有显式索引的老式代码(可以打包到函数中),例如:
k=1
do i=1, n
if (ymiss (i) == 1) then
y(k) = y(i)
k = k + 1
end if
end do
您想要的可以通过使用“pack”内在函数的数组内在函数来完成。将 ymiss 转换为逻辑数组: 0 --> .false., 1 --> .true.. 然后使用类似代码(在没有第二个索引的情况下进行测试):
y(1:ydim(t), t) = pack (y (:,t), ymiss (:,t))
编辑以添加示例代码,显示 Fortran 内在函数“where”、“count”和“pack”的使用。仅“where”无法解决问题,但“pack”可以。在本例中,我使用“< -90”作为 NaN。 OP 不需要步骤“y (ydim+1:LEN) = -99.0”,OP 不需要使用这些元素。
program test1
integer, parameter :: LEN = 6
real, dimension (1:LEN) :: y = [3.0, 1.0, -99.0, 6.0, 2.0, -99.0 ]
real, dimension (1:LEN) :: y2
logical, dimension (1:LEN) :: ymiss
integer :: ydim
y2 = y
write (*, '(/ "The input array:" / 6(F6.1) )' ) y
where (y < -90.0)
ymiss = .false.
elsewhere
ymiss = .true.
end where
ydim = count (ymiss)
where (ymiss) y2 = y
write (*, '(/ "Masking with where does not rearrange:" / 6(F6.1) )' ) y2
y (1:ydim) = pack (y, ymiss)
y (ydim+1:LEN) = -99.0
write (*, '(/ "After using pack, and ""erasing"" the end:" / 6(F6.1) )' ) y
stop
end program test1
输出是:
输入数组: 3.0 1.0 -99.0 6.0 2.0 -99.0
使用 where 进行屏蔽不会重新排列: 3.0 1.0 -99.0 6.0 2.0 -99.0
使用 pack 后,并“删除”结尾: 3.0 1.0 6.0 2.0 -99.0 -99.0
关于vector - 如何在Fortran中排列向量的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2004771/