将条件和从FORTRAN转换为R

时间:2017-07-01 22:07:52

标签: r fortran

我正在将FORTRAN代码转换为R并且遇到条件和。

我的代码的一些上下文: 我正在寻找每小时在表面上的质量积累和雨水清洁表面。如果降雨量低于1.5厘米,那么小时内的质量累积总和,但如果降雨高于1.5厘米阈值,则清除质量累积总和并重置为零。在接下来的几个小时内,重复该过程,总量积累直到雨水高于1.5,然后质量累积回到零。

所以在FORTRAN中,我逐行遍历一个数组(使用DO LOOP)并计算该小时的总质量累积,“mtot”。如果在那个小时内经历的相应降雨小于1.5厘米,我将这个mtot值加总为“msum”。如果降雨高于1.5,则将msum和mtot设置为零,因为现在表面在那个小时内没有经历质量累积,并且先前的质量被清除掉。然后我转到下一次迭代并重新计算该小时的mtot并重复相同的逻辑。所以我在i小时的mtot上存储了i + 1小时的mtot。

这是我的FORTRAN代码:

DO i = 1, 8760
    ...
    mtot = ...


    IF (rain_hourly(i) >= 1.5) THEN             ! did it rain, was the rain enough to clean the surface, threshold to clean is 1.5 cm an hour
        msum = 0.0
        mtot = 0.0
    ELSE                                        ! sum mass on surface if it didnt rain enough
        msum = msum + mtot
    END IF

    ...
END DO

我需要帮助的地方是将我的IF块翻译成R.在R中我一次计算每小时的mtot并且每小时都有一组mtot。我想我正在寻找一个条件,如果将值加起来直到在每小时mtot数组中看到的最后一个零。我是R的新手,我不确定如何接近它。我可以想到在FORTRAN中有很多不同的方法,但是我说我是R的新手并且不太了解R基本上是怎么想的。

我创建了一个表来帮助更好地解释我想要做的事情。每小时雨量列包含一小时内以厘米为单位的降雨量,回想一下清洁表面的阈值为1.5厘米。每小时mtot列是每小时累积的质量。请注意,如果每小时雨量列符合1.5的阈值,则该小时的每小时mtot将被覆盖为零。最后,如果未满足降雨阈值,则总和mtot列是同一行mtot和过去mtot的总和。请注意,总和中包含的过去的mtots只会在上次达到降雨阈值之前返回。

**Hourly Rain** **Hourly mtot** **Summed mtot** 1 3 3 1 1 4 1 2 6 1.5 0 -> 1 0 1 2 2 1.5 0 -> 1 0 1 3 3 1 1 4 1 1 5

1 个答案:

答案 0 :(得分:2)

使用data.table包可以将其实现为“单行”:

library(data.table)
data.table(DF)[, new := (hourly.rain < 1.5) * cumsum(hourly.mtot), 
               by = rleid(hourly.rain < 1.5)][]
   hourly.rain hourly.mtot summed.mtot new
1:         1.0           3           3   3
2:         1.0           1           4   4
3:         1.0           2           6   6
4:         1.5           1           0   0
5:         1.0           2           2   2
6:         1.5           1           0   0
7:         1.0           3           3   3
8:         1.0           1           4   4
9:         1.0           1           5   5

rleid(hourly.rain < 1.5)为低于或高于阈值的每条条纹值创建唯一的组ID。累计和的计算在每个组内重新开始。当达到或超过阈值时,与rleid(hourly.rain < 1.5)的乘法会强制结果变为零。因此,当强制转换为数字类型时,使用TRUE和FALSE变为1和0的事实。

数据

DF <- structure(list(hourly.rain = c(1, 1, 1, 1.5, 1, 1.5, 1, 1, 1), 
    hourly.mtot = c(3L, 1L, 2L, 1L, 2L, 1L, 3L, 1L, 1L), summed.mtot = c(3L, 
    4L, 6L, 0L, 2L, 0L, 3L, 4L, 5L)), .Names = c("hourly.rain", 
"hourly.mtot", "summed.mtot"), row.names = c(NA, -9L), class = "data.frame")