我正在尝试为滚动窗口(例如12磅)中的字符列(但按组)创建一个更改数量的指示器。如果不进行分组,则rollapply
和data.table的uniqueN
可以使用 data.table :
library(data.table)
library(zoo)
df <- data.table(id = c(rep(1:5, each = 53), 5),
time = c(rep(1:53, times = 5), 54),
geo = c("E","E","E","B","B","B","B","B","B","B","A","A","A","A","A","A","A","C","C","C","C","C","C","C","G","G","G","G","G","G","G","G","G","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","D","D","D","D","D","D","G","G","G","G","G","E","E","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","I","I","I","I","I","B","B","B","B","B","B","B","B","B","D","D","D","D","D","D","D","D","D","D","D","D","E","E","E","E","E","E","E","E","E","E","E","E","E","E","E","I","I","I","I","I","I","I","I","H","C","C","C","C","C","C","C","C","C","G","G","G","G","G","G","G","G","G","G","G","G","G","G","G","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","B","B","B","B","B","B","B","B","B","B","B","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","I","I","I","I","I","I","E","E","E","E","E","E","E","E","E","E","F","F","A","A","A","A","A"))
# works
df[, change := rollapply(geo, width = 12, FUN = uniqueN, na.pad = TRUE, align = "right")]
但是当我按 id 对它们进行分组时,它不起作用
# does not work
df[, change := rollapply(geo, width = 12, FUN = uniqueN, na.pad = TRUE, align = "right"), by = id]
是否有一种方法可以滚动唯一计数,最好使用 data.table ?
答案 0 :(得分:1)
通过将rollapply
函数包装在as.numeric
中解决了该问题,因为变量 change 被创建为逻辑变量,无法处理0和1(以及NA)以外的数字)。
如果我们将此问题保留为开放状态,这可能对其他人有帮助。
# works
df[, change := as.numeric(rollapplyr(geo, width = 12, FUN = uniqueN, fill = NA)), by = id]
答案 1 :(得分:1)
rollapply
即将推出新的快速版本data.table
功能。它称为frollapply
。速度不是真的那么快,但是仍然应该加快速度。
速度并不是真的那么快,因为在滚动窗口的每次迭代中都必须回退到R的C eval
函数。
它接受数字或逻辑输入,因此要处理您的数据,我们需要创建一个临时ngeo
列。
library(data.table)
library(zoo)
df = data.table(
id = c(rep(1:5, each = 53), 5), time = c(rep(1:53, times = 5), 54),
geo = c("E","E","E","B","B","B","B","B","B","B","A","A","A","A","A","A","A","C","C","C","C","C","C","C","G","G","G","G","G","G","G","G","G","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","D","D","D","D","D","D","G","G","G","G","G","E","E","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","I","I","I","I","I","B","B","B","B","B","B","B","B","B","D","D","D","D","D","D","D","D","D","D","D","D","E","E","E","E","E","E","E","E","E","E","E","E","E","E","E","I","I","I","I","I","I","I","I","H","C","C","C","C","C","C","C","C","C","G","G","G","G","G","G","G","G","G","G","G","G","G","G","G","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","B","B","B","B","B","B","B","B","B","B","B","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","I","I","I","I","I","I","E","E","E","E","E","E","E","E","E","E","F","F","A","A","A","A","A")
)
dt = copy(df)
# zoo rollapply
df[, change := as.numeric(rollapplyr(geo, width=12, FUN=uniqueN, fill=NA)), by=id]
# data.table frollapply
dt[, ngeo := unclass(as.factor(geo))]
dt[, change := frollapply(ngeo, 12L, FUN=uniqueN), by=id]
dt[, ngeo := NULL]
all.equal(dt, df)
#[1] TRUE
它尚未合并到data.table的主分支中,要尝试,您必须
devtools::install_github("Rdatatable/data.table@frollapply")