我如何模仿新行的拖动功能,如在Excel中,但为R?



我对lead()lag()有些不安,它们不是为每个填充的行动态/顺序拖动的。

我的愿望是填补一个新行基于一个初始值,然后按顺序填下一行基于以前行。在Excel中,这可以通过在单元格中声明公式/函数并拖动它来完成。怎么用R表示呢?

见下面的例子

x     y     z
<dbl> <dbl> <dbl>
1     1     1     1
2     2     3    NA
3     3     5    NA
4     4     7    NA
5     5     9    NA
6     6    11    NA
7     7    13    NA
8     8    15    NA
9     9    17    NA
10    10    19    NA 

期望的输出如下计算,其中t-1是前一个值的下标:Z = Z_t-1 + X_t-1 - Y_t-1.

所需输出

x     y     z
<dbl> <dbl> <dbl>
1     1     1     1
2     2     3     1
3     3     5     0
4     4     7    -2
5     5     9    -6
6     6    11    -12
7     7    13    -18
8     8    15    -25
9     9    17    -33
10    10    19    -42 

请注意,您的问题中期望的结果与您描述的公式的输出不匹配。

在这种情况下,您可以通过使用cumsum(累积和)得到答案:

cumsum(df1$x - df1$y + 1)
[1]   1   1   0  -2  -5  -9 -14 -20 -27 -35

然而,,如果你想申请一个函数递归地基于先前的输出结果,你需要写一个循环(或使用一个函数,使用一个循环"hood"下,与accumulateakrun显示)。在base R中实现您的结果的一个简单循环是:

for(i in 2:nrow(df1)) df1$z[i] <- df1$z[i-1] + df1$x[i-1] - df1$y[i-1] 
df
#>     x  y   z
#> 1   1  1   1
#> 2   2  3   1
#> 3   3  5   0
#> 4   4  7  -2
#> 5   5  9  -5
#> 6   6 11  -9
#> 7   7 13 -14
#> 8   8 15 -20
#> 9   9 17 -27
#> 10 10 19 -35

当你可以使用像cumsum这样的函数在R中使用基于c的向量化而不是循环时,它可能是一个更有效的解决方案。

与注释中一样,根据指定的公式,期望的输出不匹配。在tidyverse中,递归操作可以通过accumulate

完成。
library(purrr)
library(dplyr)
df1 %>% 
mutate(z = unlist(accumulate2(x, y, ~ ..1 + ..2 - ..3, 
.init = first(z))[-(n()+1)]))

与产出

x  y   z
1   1  1   1
2   2  3   1
3   3  5   0
4   4  7  -2
5   5  9  -5
6   6 11  -9
7   7 13 -14
8   8 15 -20
9   9 17 -27
10 10 19 -35

数据
df1 <- structure(list(x = 1:10, y = c(1L, 3L, 5L, 7L, 9L, 11L, 13L, 
15L, 17L, 19L), z = c(1L, NA, NA, NA, NA, NA, NA, NA, NA, NA)), 
class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10"))

最新更新