R Dplyr;计算上一行的两列之间的差异,但将结果放入下一行而不进行for循环

时间:2019-01-17 18:05:45

标签: r dplyr

我正在尝试解决以下问题,在该问题中,我希望使用R中的dplyr(最好不使用循环)来计算下一行的上一行与上一行的两列之差。在此特定示例中,我想从上一行计算r_j-s_j,然后将结果粘贴到下一行。

以下是一些示例数据:

require(tidyverse)
data = tibble(LM = c(100, 300, 400, 500, 600, 700, 800, 1300), s_j = c(2,2,2,1,2,2,1,1)) %>% 
       bind_cols(,r_j = rep(25, nrow(.))

     LM   s_j   r_j
1   100     2    25
2   300     2    25
3   400     2    25
4   500     1    25
5   600     2    25
6   700     2    25
7   800     1    25
8  1300     1    25

我想要的输出是这个

     LM   s_j   r_j
1   100     2    25
2   300     2    23
3   400     2    21
4   500     1    19
5   600     2    18
6   700     2    16
7   800     1    14
8  1300     1    13

解决此问题的方法是:

for (k in 2:nrow(data)){ 
   tmp = data$r_j[k-1] - data$s_j[k-1]
   data$r_j[k] = tmp 
}

产生

     LM   s_j   r_j
1   100     2    25
2   300     2    23
3   400     2    21
4   500     1    19
5   600     2    18
6   700     2    16
7   800     1    14
8  1300     1    13

但是肯定存在比R中的for循环更好的解决方案吗?感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

一种方法是生成s_j的累加和,然后从r_j中减去

Hosted

编辑:要生成所需的准确输出,可以从其总和中减去s_j的值,并获得以下信息:

data %>% mutate(
    temp = cumsum(s_j),
    r_j2 = r_j-temp
)
# A tibble: 8 x 5
     LM   s_j   r_j  temp  r_j2
   <dbl> <dbl> <dbl> <dbl> <dbl>
1   100     2    25     2    23
2   300     2    25     4    21
3   400     2    25     6    19
4   500     1    25     7    18
5   600     2    25     9    16
6   700     2    25    11    14
7   800     1    25    12    13
8  1300     1    25    13    12

EDIT2 :包括IceCreamToucan的解决方案,该解决方案无需生成临时列:

data %>% mutate(
     temp = cumsum(s_j)-s_j,
     r_j2 = r_j-temp
 )
# A tibble: 8 x 5
     LM   s_j   r_j  temp  r_j2
  <dbl> <dbl> <dbl> <dbl> <dbl>
1   100     2    25     0    25
2   300     2    25     2    23
3   400     2    25     4    21
4   500     1    25     6    19
5   600     2    25     7    18
6   700     2    25     9    16
7   800     1    25    11    14
8  1300     1    25    12    13