在R中寻找as.Date()函数的解释

fil*_*s21 6 r

我将一年中的某一天转换为日期,我注意到这as.Date通常会让意外(对我而言)结果.为什么我会为这些命令得到这样不同的答案?

as.Date(x =  1, format = '%j', origin= '2015-01-01')
Run Code Online (Sandbox Code Playgroud)

回报 "2018-07-21"

as.Date(x = 1, origin= '2015-01-01')
Run Code Online (Sandbox Code Playgroud)

回报 "2015-01-02"

as.Date(x =  1, format = '%j', origin= as.Date('2015-01-01'))
Run Code Online (Sandbox Code Playgroud)

回报 "2015-01-02"

as.Date(x = '1',format = '%j', origin= '2015-01-01')
Run Code Online (Sandbox Code Playgroud)

回报 "2018-01-01"

as.Date(x = '1', origin= '2015-01-01')
Run Code Online (Sandbox Code Playgroud)

返回错误: Error in charToDate(x) : character string is not in a standard unambiguous format

小智 3

我试图通过查看methods下各种定义的定义S3 generic as.Date,以及通过 RStudio 调试代码并查看调用函数的历史记录来部分回答下面的问题。

as.Date.numericas.Date.character的定义as.Date.default在答案的底部提供。

我定义了自己的函数check来调试发生的情况。

check <- function() {

as.Date(x =  1, format = '%j', origin= '2015-01-01')
as.Date(x = 1, origin= '2015-01-01')

}
Run Code Online (Sandbox Code Playgroud)

在第一次调用中,UseMethodofas.Date被调用,并将其分派给as.Date.numericas.Date(origin, ...)这又是现在被分派到的调用as.Date.character。如果您查看 的源代码as.Date.character,则条件为 FALSE,因为本例中已提供if missing(format)格式。%j所以被调用的代码是strptime(x, format, tz = "GMT"). 这将返回最后一次调用2018-07-20 IST转换为的值。请注意,时区可能会根据您所在的国家/地区而有所不同。内部调用无法使用此过程进行调试的 C 函数。2018-07-20as.Datestrptime

在第二次调用中,主要区别在于用户未提供格式字符串。因此,按照上述相同的过程,当条件为 TRUE 时,调用的是charToDate内部定义的函数as.Date.character,而不是内部定义的函数。在这种情况下,尝试默认格式并在 中找到匹配项。在这种情况下,提供正确的格式并计算正确的值。现在将其添加到其中,即 1 - 记住字符版本是由代码所在的数字版本调用的。这提供了正确的答案。strptimeif missing(format)charToDate'%Y-%m-%dstrptime2015-01-01xas.Date(origin, ...) + x

虽然它没有为您的问题提供完整的答案,但一般情况是它在很大程度上取决于传递给 的格式字符串strptime。希望这可以帮助。

as.日期.数字

function (x, origin, ...)
{
  if (missing(origin))
    stop("'origin' must be supplied")
  as.Date(origin, ...) + x
}
Run Code Online (Sandbox Code Playgroud)

as.日期.字符

function (x, format, tryFormats = c("%Y-%m-%d", "%Y/%m/%d"),
          optional = FALSE, ...)
{
  charToDate <- function(x) {
    xx <- x[1L]
    if (is.na(xx)) {
      j <- 1L
      while (is.na(xx) && (j <- j + 1L) <= length(x)) xx <- x[j]
      if (is.na(xx))
        f <- "%Y-%m-%d"
    }
    if (is.na(xx))
      strptime(x, f)
    else {
      for (ff in tryFormats) if (!is.na(strptime(xx, ff,
                                                 tz = "GMT")))
        return(strptime(x, ff))
      if (optional)
        as.Date.character(rep.int(NA_character_, length(x)),
                          "%Y-%m-%d")
      else stop("character string is not in a standard unambiguous format")
    }
  }
  res <- if (missing(format))
    charToDate(x)
  else strptime(x, format, tz = "GMT")
  as.Date(res)
}
Run Code Online (Sandbox Code Playgroud)

as.Date.default

function (x, ...)
{
  if (inherits(x, "Date"))
    x
  else if (is.logical(x) && all(is.na(x)))
    .Date(as.numeric(x))
  else stop(gettextf("do not know how to convert '%s' to class %s",
                     deparse(substitute(x)), dQuote("Date")), domain = NA)
}
Run Code Online (Sandbox Code Playgroud)

  • 这个答案非常完整。简短版本:如果“x”是数字,则“format”仅用于“origin”。如果“x”是字符,则忽略“origin”。 (3认同)