在R中循环以求除t之前的所有时间的总和

时间:2016-06-06 23:06:45

标签: r

我有一系列净碳吸收值(NCU)随时间变化。我想根据以下内容通过循环创建一系列新的净碳释放值(NCR):

  1. 时间t的NCR是在时间段C之前的所有其他时间段内t释放的总和。
  2. C期间的t版本可以通过潜在NCU在时间t和时间t−1的差异来计算。
  3. NCU在每个期间的开头添加。
  4. 我正在使用的论文使模型基于状态,这是一种数学技巧,用于跟踪不同时间间隔的分解。从NCRsubt = sum(NCUsub[t] - NCUsub[t-1])t=1的等式为t = T

    这是我到目前为止所拥有的:

    dt = 0.005          # Time step in years 
    duration = 15       # Simulation runs for 15, 500 yr intervals 
    n = duration/dt + 1 # Number of step including the starting point 
    time = (0:(n-1))*dt # The time in unit 500 yr intervals
    
    NCR = numeric(n)
    
    for (i in 1:(n-1)){
    
     NCR[i] = NCU[i] + (NCU[i] - NCU[i-1]) 
    
    }
    

    我无法弄清楚如何在所有时间内完成上述循环的总和NCR[i]小于给定时间。

    NCU有两个变量,time(x)(以500年为间隔),1:15NCU (y)

    修改

    以下是示例值:

    NCU值

      

    NCU = c(52.02080416,55.0440176,77.09245546,80.12810245,71.14214209,60.14417294,36.10094125,66.21153828,64.23081522,61.24448865,54.23812349)

    NCUt - NCUt-1值

      

    NCUt_NCUt_1 = c(-3.023213444,-22.04843786,-3.035646992,8.98596036,10.99796916,24.04323169,-30.11059703,1.980723063,2.986326567,7.006365164)

    NCRt值

      

    NCRt = c(10.77406468,13.79727813,35.84571598,38.88136298,29.89540262,18.89743346,-5.145798226,24.9647988,22.98407574,19.99774917)

    Excel计算的屏幕截图:

    Excel screenshot of the calculations

2 个答案:

答案 0 :(得分:1)

好的,让我们快速回答一下。

# Load in the data
# This includes the all the data within the screenshot (1:15) vs. (1:11)
NCU = c(52.02080416,55.0440176,77.09245546,80.12810245,71.14214209,60.14417294,36.10094125,66.21153828,64.23081522,61.24448865,54.23812349, 65.31275,58.30238552, 51.28640117, 41.24673948)

# Reverse the difference e.g. -1*([t] - [t-1]) => [t-1]-[t] 
dncu = -1*diff(NCU)

# Here is a function to use within `sapply()`
# The function provides the sum from x up to the length of the differenced
# ncu data.
calc_NCR = function(x, dncu, len_dncu){ 
   sum(dncu[x:len_dncu])
}

# Length of the differenced ncu data
len_dncu = length(dncu)

# A vectorized for loop for speed. 
# range is given from 1 to the length of differenced data. 
sapply(1:len_dncu, FUN = calc_NCR, dncu = ncut_ncut_1, len_dncu = len_dncu)

结果(在as.matrix()上使用sapply()后使其看起来很漂亮):

           [,1]
 [1,] 10.774065
 [2,] 13.797278
 [3,] 35.845716
 [4,] 38.881363
 [5,] 29.895403
 [6,] 18.897433
 [7,] -5.145798
 [8,] 24.964799
 [9,] 22.984076
[10,] 19.997749
[11,] 12.991384
[12,] 24.066011
[13,] 17.055646
[14,] 10.039662

答案 1 :(得分:1)

用另一种方法补充Coatless的好答案:

# as in the other answer
dncu = -1*diff(NCU)

cumsum函数给出了向量的累积和,例如

cumsum(1:5)
# [1]  1  3  6 10 15

您需要累积金额,但需要向后。而不是第一,第一+第二,第一+第二+第三,...你正在寻找最后,最后+倒数第二,......

我们可以通过简单地用rev()反转输入向量来实现。然后我们也会反转结果,使其顺序正确:

rev(cumsum(rev(dncu)))
# [1] 10.774065 13.797278 35.845716 38.881363 29.895403 18.897433 -5.145798 24.964799
# [9] 22.984076 19.997749 12.991384 24.066011 17.055646 10.039662

您正在寻找的是什么!

我确实认为你在自己身上做的事情要比他们需要的时候更加困难。如果您订购的时间最早到最新,那么

forwardNCU = rev(NCU)
cumsum(diff(forwardNCU)) 

给出相同的结果(按顺序排列)。