【问题标题】:weighted rolling median in data.table (r)data.table (r) 中的加权滚动中位数
【发布时间】:2019-01-31 17:40:07
【问题描述】:

我知道有很多函数计算滚动中位数,但我找不到任何计算 加权 滚动中位数的函数(我找到了 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 的类型('logical')必须与 LHS('double')匹配。对于最快的情况,检查和强制会影响性能。要么更改目标列的类型,要么自己强制 := 的 RHS(例如,使用 1L 而不是 1)

【问题讨论】:

  • 我试过你的代码,它给了我与你的问题无关的错误(最初是unused argument (na.rm = TRUE),然后当我将它添加到你的weight_median_calc 时,我得到'x' and 'w' must have the same length)。同样,我必须在代码中添加library(data.table);library(zoo),请包括所有正在使用的非基础 R 包。我建议您开始一个新的 R 会话(不恢复!)并使用您的代码,修复错误,然后更新您的问题。
  • @r2evans 感谢您的建议!我已经编辑过了。

标签: r data.table weighted rollapply


【解决方案1】:

您的代码存在很多问题。导致您当前错误的主要问题是由rollapplyfill = NA 参数引起的。默认情况下,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)
}

要解决的第三个问题是您对lag 的使用。 lag 没有 n= 参数。在 data.table 中,您可能应该改用 shift

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

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

【讨论】:

    猜你喜欢
    • 2012-08-15
    • 2023-03-11
    • 2021-11-29
    • 1970-01-01
    • 2020-07-10
    • 2021-04-21
    • 2014-06-29
    • 1970-01-01
    • 2017-08-23
    相关资源
    最近更新 更多