在 lapply() data.table 设置中组合 rollapply() 和 weighted.mean() 时出错
Error when combining rollapply() and weighted.mean() in an lapply() data.table setting
我运行以下代码:
id <- c(67, 39, 39, 39, 39, 39, 39, 39, 58, 58, 58, 58, 58, 58)
ratio <- c(0.5421248, 0.1558647, 0.1314578, 0.1095102, 0.1149908, 0.1645262, 0.1431160, 0.1633623,
1.1375268, 1.3219208, 1.3830684, 1.5942101, 0.5991420, 0.6303874)
DT <- data.table(id, ratio)
DT[, lapply(.SD,
function(x) rollapplyr(x,
width = 3,
weighted.mean,
w = c(0.2, 0.3, 0.5),
align = 'right',
fill = NA)),
by = id,
.SDcols = 'ratio']
并且出现以下错误:
Error in `[.data.table`(DT, , lapply(.SD, function(x) rollapplyr(x, width = 3, :
Column 1 of result for group 2 is type 'double' but expecting type 'logical'. Column types must be consistent for each group.
当我像这样排除第一行时:
DT[2:14, lapply(.SD,
function(x) rollapplyr(x,
width = 3,
weighted.mean,
w = c(0.2, 0.3, 0.5),
align = 'right',
fill = NA)),
by = id,
.SDcols = 'ratio']
我没有收到错误。我想这与只有一个 id = 67 有关。
有没有办法避免这个错误,只为 id 67 获取 NA?
我真的不明白为什么它不起作用,因为它有效:
rollapplyr(ratio,
width = 3,
weighted.mean,
w = c(0.2, 0.3, 0.5),
align = 'right',
fill = NA)
来自安德鲁的评论:
DT[, lapply(.SD, zoo::rollapplyr,
width = 3, FUN = weighted.mean,
w = c(0.2, 0.3, 0.5), fill = NA_real_),
by = id, .SDcols = 'ratio']
# id ratio
# 1: 67 NA
# 2: 39 NA
# 3: 39 NA
# 4: 39 0.1253654
# 5: 39 0.1166400
# 6: 39 0.1386624
# 7: 39 0.1439140
# 8: 39 0.1575212
# 9: 58 NA
# 10: 58 NA
# 11: 58 1.3156158
# 12: 58 1.4764097
# 13: 58 1.0544477
# 14: 58 0.8137783
这里做的两处改动:
NA
到 NA_real_
。许多函数强制保留 class 操作;在这种情况下,zoo::rollapplyr
的输入 class 为 numeric
,但 class(NA)
returns logical
。现在可能是注意到 NA
实际上至少有七个变体的好时机:NA
(逻辑)、NA_integer_
、NA_real_
、NA_character_
、c.Date(NA)
、c.POSIXlt(NA)
和 c.POSIXct(NA)
。其中一些记录在 ?NA
中,其他的是通过探索发现的。 (class 的这种保留也存在于 dplyr::if_else
和 data.table::fifelse
等函数中,但遗憾的是 base 的 ifelse
没有。)
当然不是错误,而是删除了align="right"
,因为在这种情况下使用[=30是多余的=] 函数(尾部 r
表示 "right")。
我运行以下代码:
id <- c(67, 39, 39, 39, 39, 39, 39, 39, 58, 58, 58, 58, 58, 58)
ratio <- c(0.5421248, 0.1558647, 0.1314578, 0.1095102, 0.1149908, 0.1645262, 0.1431160, 0.1633623,
1.1375268, 1.3219208, 1.3830684, 1.5942101, 0.5991420, 0.6303874)
DT <- data.table(id, ratio)
DT[, lapply(.SD,
function(x) rollapplyr(x,
width = 3,
weighted.mean,
w = c(0.2, 0.3, 0.5),
align = 'right',
fill = NA)),
by = id,
.SDcols = 'ratio']
并且出现以下错误:
Error in `[.data.table`(DT, , lapply(.SD, function(x) rollapplyr(x, width = 3, :
Column 1 of result for group 2 is type 'double' but expecting type 'logical'. Column types must be consistent for each group.
当我像这样排除第一行时:
DT[2:14, lapply(.SD,
function(x) rollapplyr(x,
width = 3,
weighted.mean,
w = c(0.2, 0.3, 0.5),
align = 'right',
fill = NA)),
by = id,
.SDcols = 'ratio']
我没有收到错误。我想这与只有一个 id = 67 有关。
有没有办法避免这个错误,只为 id 67 获取 NA?
我真的不明白为什么它不起作用,因为它有效:
rollapplyr(ratio,
width = 3,
weighted.mean,
w = c(0.2, 0.3, 0.5),
align = 'right',
fill = NA)
来自安德鲁的评论:
DT[, lapply(.SD, zoo::rollapplyr,
width = 3, FUN = weighted.mean,
w = c(0.2, 0.3, 0.5), fill = NA_real_),
by = id, .SDcols = 'ratio']
# id ratio
# 1: 67 NA
# 2: 39 NA
# 3: 39 NA
# 4: 39 0.1253654
# 5: 39 0.1166400
# 6: 39 0.1386624
# 7: 39 0.1439140
# 8: 39 0.1575212
# 9: 58 NA
# 10: 58 NA
# 11: 58 1.3156158
# 12: 58 1.4764097
# 13: 58 1.0544477
# 14: 58 0.8137783
这里做的两处改动:
NA
到NA_real_
。许多函数强制保留 class 操作;在这种情况下,zoo::rollapplyr
的输入 class 为numeric
,但class(NA)
returnslogical
。现在可能是注意到NA
实际上至少有七个变体的好时机:NA
(逻辑)、NA_integer_
、NA_real_
、NA_character_
、c.Date(NA)
、c.POSIXlt(NA)
和c.POSIXct(NA)
。其中一些记录在?NA
中,其他的是通过探索发现的。 (class 的这种保留也存在于dplyr::if_else
和data.table::fifelse
等函数中,但遗憾的是 base 的ifelse
没有。)当然不是错误,而是删除了
align="right"
,因为在这种情况下使用[=30是多余的=] 函数(尾部r
表示 "right")。