r - 使用 dplyr 对两个变量进行递归求和
问题描述
我有两列的值,a 和 b。我想添加第三列c,它是(在第i行)b的0到i的总和加上c的0到(i-1)的总和,乘以a,即
c_i = (sum_i (b) + sum_(i-1) (c) ) * a_i
我试过
data %>%
mutate(
c = a * (cumsum(b) + lag(cumsum(c), default = 0))
)
但是这不起作用,因为我只是根据目前不存在的 c 值创建 c :
Error: Problem with `mutate()` input `c`. x object 'c' not found
以前我使用 for 循环处理此类问题。但是,我习惯了 dplyr,而且总有办法。但是,我不明白。
我很感激任何帮助!
编辑:在以前的版本中,我不准确,因为 a 也是一个向量,而不是一个常数。我在公式里改了
所需的输出:
row 1: 0.5 * (7 + 0 ) =3.5
row 2: 0.3 * (7+1 + 3.5) = 3.45
row 3: 1.0 * (7+1+9 + 3.5+3.45) = 23.95
| a | b | c |
|---|---|---|
|0.5|7|3.5|
|0.3|1|3.45|
|1|9|23.95|
|0.2|10|...|
解决方案
更新
一个超级有效的选择是求解线性矩阵(感谢@Martin Gal 的评论):
transform(
df,
C = solve(
`diag<-`(mat <- matrix(-a, length(a), length(a)), 1) * lower.tri(mat, diag = TRUE),
a * cumsum(b)
)
)
这使
a b C
1 0.5 7 3.5000
2 0.3 1 3.4500
3 1.0 9 23.9500
4 0.2 10 11.5800
5 0.4 3 28.9920
6 0.8 2 82.7776
或以某种dplyr
方式
df %>%
mutate(
C = solve(
`diag<-`(mat <- matrix(-a, length(a), length(a)), 1) * lower.tri(mat, diag = TRUE),
a * cumsum(b)
)
)
这使
# A tibble: 6 x 3
a b C
<dbl> <int> <dbl>
1 0.5 7 3.5
2 0.3 1 3.45
3 1 9 24.0
4 0.2 10 11.6
5 0.4 3 29.0
6 0.8 2 82.8
上一个答案(递归方法,无效)
通过定义递归函数的基本 R 选项(但效率低下)f
f <- function(k) {
if (k == 1) {
return(with(df[k, ], a * b))
}
r <- f(k - 1)
c(r, with(df, a[k] * (sum(b[1:k]) + sum(r))))
}
你会看到
> f(nrow(df))
[1] 3.5000 3.4500 23.9500 11.5800 28.9920 82.7776
和
> df %>%
+ mutate(C = f(n()))
# A tibble: 6 x 3
a b C
<dbl> <int> <dbl>
1 0.5 7 3.5
2 0.3 1 3.45
3 1 9 24.0
4 0.2 10 11.6
5 0.4 3 29.0
6 0.8 2 82.8
推荐阅读
- c++ - 如何查看完整的 CMD 执行命令,包括参数和标志?
- node.js - Angular 6 passport-facebook 不适用于 Heroku
- java - 如何使用带有消息集线器的 kafkacat
- android - 将项目添加到数组
- docker - 如何在通过 CircleCI 运行的 Ubuntu 中启动 Redis
- web - 如何在图像中显示的网页上制作窗帘效果?
- reactjs - 当值在字段中时,Redux-From getFormValues() 返回未定义
- c++ - 在 Windows 中从 Github 存储库创建静态库
- angularjs - AngularJS - 使用 $compile 时无法访问组件中的 ng-click
- r - 如何在 R 中的 RMySQL 中要求 SSL?