na.fill 显示意外结果的日期

na.fill for date showing the unexpected results

我尝试使用 zoo::na.fill 将日期向量中的 NA na 值替换为另一个值,但它用“1970-01-02”替换了我的 NA 值比我指定的值:

library(zoo)
a <- as.Date(c(NA, '2018-01-01'))

na.fill(a, as.Date('2018-01-02'))
[1] "1970-01-02" "2018-01-01"

为什么会这样?这是一个错误还是我需要指定一些东西才能按预期工作 注意:我知道我们可以使用 a[is.na(a)] <- as.Date('2018-01-02') 但这个问题是关于 na.fill in zoo

亲爱的zoo::na.*功能

zoo 包是处理 NA 值的函数的绝佳来源,它们一直广泛用于非 zoo 对象,但它们是为时间序列编写的带有索引的值。 zoo::na.* 的行为有时会在非数字向量上按预期工作,但有时不会,如 zoo::na.fill 和其他一些情况。

他们在 Date 向量上的行为概述

一些示例数据。我们使用 zoo::as.Date 这样我就不用每次都给出来源了。

(a <- zoo::as.Date(c(10000, NA, 10002)))
#> [1] "1997-05-19" NA           "1997-05-21"
(b <- zoo::as.Date(10001))
#> [1] "1997-05-20"

zoo::na.aggregate(a) # As expected
#> [1] "1997-05-19" "1997-05-20" "1997-05-21"
zoo::na.approx(a) # Converts to numeric
#> [1] 10000 10001 10002
zoo::as.Date(zoo::na.approx(a)) # Workaround
#> [1] "1997-05-19" "1997-05-20" "1997-05-21"
zoo::na.fill(a, b) # Coerces b to logical TRUE then to numeric - see below
#> [1] "1997-05-19" "1970-01-02" "1997-05-21"
zoo::as.Date(zoo::na.fill(as.numeric(a), as.numeric(b))) # Workaround
#> [1] "1997-05-19" "1997-05-20" "1997-05-21"
zoo::na.locf(a) # As expected
#> [1] "1997-05-19" "1997-05-19" "1997-05-21"
zoo::na.spline(a) # Converts to numeric
#> [1] 10000 10001 10002
zoo::as.Date(zoo::na.spline(a)) # Workaround
#> [1] "1997-05-19" "1997-05-20" "1997-05-21"
zoo::na.trim(c(NA, NA, a, NA, NA)) # Converts to numeric
#> [1] 10000    NA 10002
zoo::as.Date(zoo::na.trim(c(NA, NA, a, NA, NA))) # Workaround
#> [1] "1997-05-19" NA           "1997-05-21"

zoo::na.fillDate 向量上的详细信息

na.fill.zoo 的源代码中(最终完成工作)是这样的:

as.cls <- if (is.integer(coredata(object))) {
      as.integer
    }
    else if (is.numeric(coredata(object))) {
      as.numeric
    }
    else if (is.character(coredata(object))) {
      as.character
    }
    else {
      as.logical
    }

class(coredata(object))等同于class(a)Date。由于没有 Date 选项,因此 as.cls 默认为 as.logical

接下来发生的事情是 fill 参数(本质上)应用了 as.cls。在这种情况下 fill 是一个非零 Date,它被强制转换为用于填充 NA.

的数字 1

然后在最后 return 值被强制转换为 object 的 class,即日期。当然 as.Date(1)1970-01-02.