问题
I want to rollapply a function on a data.table. And in the function I would like to work with the data.table subset, so that the example below works.
library(zoo)
library(data.table)
dt <- data.table(i = 1:100,
x = sample(1:10, 100, replace = T),
y = sample(1:10, 100, replace = T))
rollapply(dt, width=10, FUN = function(dt_slice) dt_slice[, mean(x == y)])
回答1:
You can use rollapply
, or sapply
/outer
, to get a matrix of indices and then apply
over that matrix with the operation you want
inds <- rollapply(seq_len(nrow(dt)), width = 10, FUN = I)
# or inds <- t(sapply(seq_len(1 + nrow(dt) - 10) - 1, `+`, 1:10))
# or inds <- outer(seq_len(1 + nrow(dt) - 10) - 1, 1:10, `+`)
# or inds <- embed(1:100, 10)[, 10:1] # thanks @Frank
apply(inds, 1, function(i) dt[i, mean(x == y)])
# [1] 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
# [20] 0.0 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.2 0.2 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1
# [39] 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.1 0.1 0.1 0.1 0.1
# [58] 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.0 0.0 0.0 0.0
# [77] 0.1 0.1 0.1 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.1 0.1 0.1 0.0 0.0
Although if the operation is as simple as this example you can also do
dt[, rollapply(x == y, width = 10, FUN = mean)]
回答2:
Thanks to @jangorecki for referring to the frollapply function. It is another piece of beauty added to the data.table library. For your question, you would run the following:
library(data.table)
set.seed(17)
dt <- data.table(i = 1:100,
x = sample(1:10, 100, replace = T),
y = sample(1:10, 100, replace = T))
dt$index <- dt$x == dt$y
dt[,`:=` (MA = frollapply(index,10,mean)), ]
head(dt,12)
来源:https://stackoverflow.com/questions/56444872/rollapply-over-data-table-rows-with-subset-calculations-in-function