数据表(R)中的加权滚动中位数



我知道很多函数计算滚动中位数,但我找不到任何计算加权滚动中位数的东西(我找到了ema,但那是平均值)。这是我尝试过的

2019年1月31日编辑:我发现当我只按 V2 分组时,代码工作正常。仅当我按 V2:V4 分组时才会发生错误

library(spatstat)
library(data.table)
library(zoo)

a <- data.table(V1 = c(rep(NA, 10), runif(90)), 
                V2 = c(rep('good', 50), rep('bad', 50)),
                V3 = c(rep('monday', 70), rep('friday', 30)),
                V4 = c(rep('male', 90), rep('female', 10)))
a <- a[,'lag1':=lag(V1, n = 1), by = .(V2)]
set.seed(55)
rn <- runif(45)
w <- sort(rn/sum(rn), decreasing = T)
weight_median_calc <- function(u){
  weighted.median(x = u,
                w = w)
}
a <- a[,'roll_weighted_median':= 1][,roll_weighted_median:=rollapply(data = lag1,
                                                                   width = 45,
                                                                   FUN = weight_median_calc,
                                                                   by.column = FALSE,
                                                                   align = 'right',
                                                                   fill = NA
),
by = .(V2, V3, V4)][]

[.data.table中的错误 (a[, := ("roll_weighted_median", 1)], := (roll_weighted_median, : RHS("逻辑")的类型必须与 LHS("双精度")匹配。对于最快的情况,检查和胁迫会对性能产生太大影响。要么更改目标列的类型,要么自己强制使用 := 的 RHS(例如,使用 1L 而不是 1)

你的代码有很多问题。 给出当前错误的主要问题是由fill = NA参数引起的 rollapply . 默认情况下,NA 的类型是逻辑的,当我们尝试使用 := 将其分配给数字向量时会发生冲突。 因此,请使用fill = as.numeric(NA) - 如下所示:

a[, roll_weighted_median := rollapply(
  data = lag1, width = 45, FUN = weight_median_calc,
    by.column = FALSE, align = 'right', fill = as.numeric(NA)),
  by = .(V2, V3, V4)][]

代码的另一个可能问题是,如果仅传递NA值,weight_median_calc将引发错误。 我们可以这样重写它以避免这些错误

weight_median_calc <- function(u){
  if (!all(is.na(u))) 
    weighted.median(x = u, w = w[1:length(u)]) 
  else as.numeric(NA)
}

要解决的第三个问题是您使用laglag没有n=论点。 在data.table中,你可能应该使用shift

a[, lag1 := shift(V1, 1), by = .(V2)]

您应该注意的最后一件事是,在data.table中,不应将<-赋值与:=赋值结合使用。 := 已经完成了分配,因此无需使用 <- 再次复制结果。 换句话说,不要做a <- a[, foo := bar]。 就做a[, foo := bar]

最新更新