基于数据帧中多个向量(列)上的先前向量元素,对向量(列)的每个元素执行算术运算

时间:2018-02-12 19:01:09

标签: r

我有一个包含12列的数据框,我需要对其中的7列执行一些基本算术:第5:12列。名为test的数据框粘贴在下面。

我想要执行的算法将根据前一个元素更改每个元素,除了每列中的第一个元素,因为每列的第一个元素的算术与后续元素不同。此外,元素向量将由等式改变,因为其涉及其原始值。我对前一行代码中的第一个元素进行了算术运算,因此它已经是正确的值。

这是数学:

B = (1-.08)Bt + .08(z)

其中Bt是前一个元素的值,z是当前元素的值。然后每个元素将成为B.

编辑:我可能不太清楚,但Bt将是前一个元素中新计算的B值。所以这有一步一步的进展。

我一直尝试使用apply,但我很困惑,因为我过去只使用for循环在单个向量上做了类似的事情,但在这种情况下,我基于以前创建了全新的向量元素元素,并且像这个例子,第一个元素是预定义的。

我可以对此进行概念化,但无法使用我目前在R中的技能集对其进行编码。

非常感谢任何帮助。谢谢。

数据:

test table

 test <- 

 structure(list(Forecast_day = c(8, 8, 8, 8, 8, 8), Forecast_date = structure(c(17555, 
    17556, 17557, 17558, 17559, 17560), class = "Date"), DeliveryDate = structure(c(17563, 
    17564, 17565, 17566, 17567, 17568), class = "Date"), HourEnding = c(1L, 
    1L, 1L, 1L, 1L, 1L), Coast = c(-0.0459999999999999, -11.6, -3.8, 
    -7.09999999999999, -9.6, -11.2), East = c(0.01, -8.5, -1.5, -3.5, 
    -0.5, -9.5), FarWest = c(-0.07, -6.5, -9, -11.5, 6, -10.5), North = c(0.01, 
    -2.5, -1.5, -1.5, 14, 0), NorthCentral = c(-0.07, -7.25, -5.75, 
    -10.75, 6.75, 1.5), SouthCentral = c(-0.01, -10, -8.5, -3.5, 
    -8.5, -11), Southern = c(-0.04, -10.8, -4.6, -7.8, -9.6, -12), 
        West = c(-0.16, -7.4, -6.6, -13.2, 7.8, -9)), .Names = c("Forecast_day", 
    "Forecast_date", "DeliveryDate", "HourEnding", "Coast", "East", 
    "FarWest", "North", "NorthCentral", "SouthCentral", "Southern", 
    "West"), row.names = c(NA, -6L), class = "data.frame")

2 个答案:

答案 0 :(得分:1)

您可以使用Reduce元函数沿向量顺序应用算法,使用前一个结果作为输入之一。

首先,将算术包装在一个函数中。

update_with_previous <- function(previous, current) {
  (1 - 0.08) * previous + 0.08 * current
}

要对一列执行此操作,请使用Reduce中的函数并设置accumulate = TRUE以保留每个结果。

Reduce(update_with_previous, test$Coast, accumulate = TRUE)
# [1] -0.046000 -0.970320 -1.196694 -1.668959 -2.303442 -3.015167

使用lapply同时替换多个列。

test[5:12] <- lapply(
  X          = test[5:12],
  FUN        = Reduce,
  f          = update_with_previous,
  accumulate = TRUE
)

答案 1 :(得分:0)

可能有更优雅的东西,但我认为这样可行:

B <- function(Bt,z) (1-.08)*Bt + .08*(z)
tmp <- sapply(test[,5:12] ,function(g) sapply(2:nrow(test),function(x) B(Bt = g[x-1],z = g[x])))
test[2:nrow(test),5:12] <-  tmp