具有 2 个向量参数的滚动函数

Rolling over function with 2 vector arguments

我想对需要 2 个向量参数的函数应用滚动。这是使用 data.table:

的示例(不起作用)
library(data.table)
df <- as.data.table(cbind.data.frame(x=1:100, y=101:200))
my_sum <- function(x, y) {
  x <- log(x)
  y <- x * y
  return(x + y)
}
roll_df <- frollapply(df, 10, function(x, y) {
  my_sum(x, y)})

无法识别 y 列。 Ofc,解决方案可以使用 xts 或其他一些包。

编辑: 这是我要应用的真实功能:

library(dpseg)
dpseg_roll <- function(time, price) {
  p <- estimateP(x=time, y=price, plot=FALSE)
  segs <- dpseg(time, price, jumps=jumps, P=p, type=type, store.matrix=TRUE)
  slope_last <- segs$segments$slope[length(segs$segments$slope)]
  return(slope_last)
}

我不知道你要用 frollapply 做什么(meansum 或其他?)。

假设您要使用滚动总和,这里可能是一个例子。我重写了您的函数 my_sum,使其直接应用于 df

my_sum <- function(...) {
  v <- c(...)
  x <- log(v[[1]])
  y <- Reduce(`*`,v)
  return(x + y)
}

roll_df <- frollapply(
  my_sum(df), 
  10,
  FUN = sum)

使用 runner 您可以在滚动 window 中应用任何功能。 运行 window 也可以在插入到 x 参数的 data.frame 行上创建。让我们关注更简单的函数 my_sum。 runner 中的参数 f 只能接受一个对象(在本例中为 data)。我鼓励在对子集应用一些花哨的模型之前,将 browser() 放入调试 row-by-row 的函数中(某些算法需要最少数量的观察)。

my_sum <- function(data) {
  # browser()
  x <- log(data$x)
  y <- x * data$y
  tail(x + y, 1) # return only one value
}

my_sum 应该 return 只有一个值,因为 runner 计算每一行 - 如果 my_sum returns 向量,你会得到一个列表. 因为 runner 是一个独立的函数,所以你需要将 data.table 对象传递给 x。最好的方法是使用 x = .SD(参见 为什么)

df[, 
   new_col := runner(
      x = .SD,
      f = my_sum,
      k = 10
)]
如果使用 coredata=FALSE,zoo 中的

rollapply 将 zoo 对象传递给要应用的函数。 zoo 对象由时间和值部分组成,因此如果 x 值表示升序值(据我所知确实如此),我们可以使用以下内容。请注意,问题 returns 中的 my_sum 如果两个参数的长度为 10,则结果为 10 个元素,因此下面显示的 out 是一个 100 x 10 的动物园对象,前 9 行填充了 NA。

如果您不想让 NA 省略 fill=NA,或者如果您想在开头将函数应用于部分输入而不是 fill=NA,请使用 partial=TRUE。如果您只想要 10 个元素中的一个,例如最后一个,则使用 function(x) my_sum(time(x), coredata(x))[10] 代替显示的函数,或者只使用 out[, 10].

如果您需要那种形式的结果,

fortify.zoo(out) 可用于将动物园对象 out 转换为数据框,或者如果您想删除时间,请使用 as.data.frame(out)as.data.table(out) 也以类似的方式工作。

library(zoo)

z <- read.zoo(df)  # df$x becomes the time part and df$y the value part
out <- rollapplyr(z, 10, function(u) my_sum(time(u), coredata(u)), 
  coredata = FALSE, fill = NA)

dim(out)
## [1] 100  10

请注意,在 dpseg_rolljumpstype 未定义。