计算阈值之间的时间

时间:2018-01-04 19:09:17

标签: r

我正在研究鱼类生物量的时间序列,并试图找出一种计算耗尽时间(生物量从> 1.0到<0.5)的方法以及恢复时间(生物量从&lt; 0.5至> 1.0)。我正在为多种鱼类重复这一点。在某些情况下,个别股票有多个耗尽和复苏事件;我想计算所有这些事件的时间。

> dput(head(example))
structure(list(id = c(550L, 558L, 569L, 561L, 572L, 548L), fish = structure(c(2L, 
2L, 2L, 2L, 2L, 2L), .Label = c("cod", "croaker"), class = "factor"), 
year = c(1996L, 1995L, 2000L, 1994L, 1997L, 2001L), biomass = c(1.34, 
1.25, 0.75, 0.61, 0.41, 0.39)), .Names = c("id", "fish", "year", 
"biomass"), row.names = c(NA, 6L), class = "data.frame")

> summary.default(example)
    Length Class  Mode   
id      80     -none- numeric
fish    80     factor numeric
year    80     -none- numeric
biomass 80     -none- numeric

1 个答案:

答案 0 :(得分:0)

这不是一个很好的解决方案,但它可以通过Twitter对话here添加帮助来理解您的问题。

因为您的示例数据不包含过渡期(对于包含您尝试检测的期间非常有帮助),我自己创建了。现在,我不包含多个物种,因此您需要将data.frames拆分出来以使用此处的解决方案。我还假设你每年只测量生物量。此解决方案要求您的数据按年份排序,否则将无法正常工作。

示例数据包含年份和生物量。我添加了一个新列state,并将所有值初始化为“稳定”。

example = data.frame(year = 1990:2010,
                     biomass=c(1.7,1.9,1.3,1.5,1.8,1.2,0.9,1.1,
                               1.0,0.6,0.4,0.6,0.7,0.9,0.8,0.4,
                               0.7,1.1,0.9,1.2,1.4))
example$state = "Stable"

现在我想确定可能过渡年的所有年份(&lt; = 1.0或&gt; = 0.5。

toCheck = which(example$biomass <= 1 & example$biomass >= 0.5)

对于这些年中的每一年,我需要确定:

  1. 真的是过渡期吗?也就是说,它是否开始&gt; 1并结束&lt; 0.5(反之亦然)或它是否会反弹到原来的位置?
  2. 是衰退还是复苏?
  3. 我使用while循环,因为我只需要考虑过渡年份的完整序列。如果生物量变为1.1-> 1.0-> 0.9-> 1.1,则没有发生任何事情,它仍然是稳定的。我们看一下可能转换的第一个案例并检查前面的值(注意,如果第一个值是可能的转换,这将不起作用)来确定我们是否可能处于下降或恢复状态。然后我使用减法来确定连续过渡期是多长。我使用它来确定过渡的结束是指示实际的下降/恢复还是只是在该空间中移动。如果它是真的,我改变状态以表明。然后我从toCheck移除连续的转换块,循环重复直到空。

    while(length(toCheck) > 0){
      i = toCheck[1]
      if(example$biomass[i-1] > 1){
        tr = which(`-`(toCheck[-1],i) == 1:(length(toCheck)-1))
        if(example$biomass[length(tr)+1+i] < 0.5) example$state[i:(i+length(tr))] = "Decline"
      } else if(example$biomass[i-1] < 0.5){
        tr = which(`-`(toCheck[-1],i) == 1:(length(toCheck)-1))
        if(example$biomass[length(tr)+1+i] > 1.0) example$state[i:(i+length(tr))] = "Recover"
      }
      toCheck = toCheck[(1:(1+length(tr)))*-1]
    }
    

    最后,rle计算游程长度

    rle(example$state)
    #> Run Length Encoding
    #>   lengths: int [1:5] 8 2 6 1 4
    #>   values : chr [1:5] "Stable" "Decline" "Stable" "Recover" "Stable"
    

    我可以在这个样本数据中看到,下降需要2年(意味着2年是&lt; = 1和&gt; = 0.5)并且恢复时间为1.然后提取相关数字并且应该是微不足道的。根据需要聚合它们。