我是R的新手,似乎无法掌握如何调用之前的“self”值,在这种情况下是前一个“b”b[-1]
。
b <- ( ( 1 / 14 ) * MyData$High + (( 13 / 14 )*b[-1]))
显然我需要在那里的某个地方进行第一次计算,但我无法自己解决这个问题。
添加所追求的结果的示例(A = MyData $ High):
A b
1 5 NA
2 10 0.7142...
3 15 3.0393...
4 20 4.6079...
答案 0 :(得分:5)
1)for循环通常人们只会使用一个简单的循环:
MyData <- data.frame(A = c(5, 10, 15, 20))
MyData$b <- 0
n <- nrow(MyData)
if (n > 1) for(i in 2:n) MyData$b[i] <- ( MyData$A[i] + 13 * MyData$b[i-1] )/ 14
MyData$b[1] <- NA
,并提供:
> MyData
A b
1 5 NA
2 10 0.7142857
3 15 1.7346939
4 20 3.0393586
2)减少也可以使用Reduce
。首先定义一个函数f
来执行循环体,然后我们Reduce
重复调用它,如下所示:
f <- function(b, A) (A + 13 * b) / 14
MyData$b <- Reduce(f, MyData$A[-1], 0, acc = TRUE)
MyData$b[1] <- NA
给出相同的结果。
这给出了矢量化的外观,但实际上如果你查看Reduce
的来源,它会自己进行for
循环。
3)过滤器注意问题的形式是一个递归过滤器,系数13/14在A / 14上运行(但A [1]替换为0)我们可以写下面的内容。由于filter
返回时间序列,因此我们使用c(...)
将其转换回普通向量。实际上,这种方法是向量化的,因为过滤操作是在C中执行的。
MyData$b <- c(filter(replace(MyData$A, 1, 0)/14, 13/14, method = "recursive"))
MyData$b[1] <- NA
再次给出相同的结果。
注意:所有解决方案都假设MyData
至少有一行。
答案 1 :(得分:3)
有几种方法可以做到这一点。
第一种方法是一个简单的循环
df <- data.frame(A = seq(5, 25, 5))
df$b <- 0
for(i in 2:nrow(df)){
df$b[i] <- (1/14)*df$A[i]+(13/14)*df$b[i-1]
}
df
A b
1 5 0.0000000
2 10 0.7142857
3 15 1.7346939
4 20 3.0393586
5 25 4.6079758
这并没有给出预期答案中给出的确切值,但它足够接近我认为你犯了转录错误。请注意,我们必须假设我们可以将NA
中的df$b[1]
视为零,或者我们将NA
一直放下。
如果您有大量数据或需要这么做,可以通过在C ++中实现代码并从R调用它来提高速度。
第二种方法使用R功能sapply
您在
中提出问题的表单是递归的,这使得它无法矢量化,但是我们可以做一些数学并发现它等同于
然后我们可以编写一个计算b_i的函数并使用sapply来计算每个元素
calc_b <- function(n,A){
(1/14)*sum((13/14)^(n-1:n)*A[1:n])
}
df2 <- data.frame(A = seq(10,25,5))
df2$b <- sapply(seq_along(df2$A), calc_b, df2$A)
df2
A b
1 10 0.7142857
2 15 1.7346939
3 20 3.0393586
4 25 4.6079758
注意:我们需要删除第一行(A = 5
),以便计算正确执行。