具有 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
做什么(mean
或 sum
或其他?)。
假设您要使用滚动总和,这里可能是一个例子。我重写了您的函数 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_roll
中 jumps
和 type
未定义。
我想对需要 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
做什么(mean
或 sum
或其他?)。
假设您要使用滚动总和,这里可能是一个例子。我重写了您的函数 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_roll
中 jumps
和 type
未定义。