我尝试通过查看S3通用as.Date
下的各种方法
的定义,以及通过RStudio调试您的代码并查看所调用函数的历史记录来部分回答以下问题。
as.Date.numeric
、as.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')
}
在第一次调用中,
as.Date
的
UseMethod
被调用,它将其分派给
as.Date.numeric
。这又调用了
as.Date(origin, ...)
,现在它被分派给
as.Date.character
。如果您查看
as.Date.character
的源代码,则条件
if missing(format)
为FALSE,因为在此情况下提供了格式
%j
。因此,被调用的代码片段是
strptime(x, format, tz = "GMT")
。这将返回
2018-07-20 IST
,最后一次调用
as.Date
将其转换为
2018-07-20
。请注意,时区可能因您所在的国家而异。
strptime
内部调用一个无法使用此过程进行调试的C函数。
在第二个调用中,主要区别在于用户未提供格式字符串。因此,按照上述相同的过程,被调用的是
as.Date.character
内部定义的
charToDate
函数,而不是
strptime
,因为条件
if missing(format)
为TRUE。在这种情况下,
charToDate
尝试默认格式,并在
'%Y-%m-%d
中找到匹配项。在这种情况下,
strptime
提供了
正确的格式,并计算出正确的值
2015-01-01
。现在将其添加到
x
中,即1-请记住,字符版本是由数字版本调用的,其中代码为
as.Date(origin, ...) + x
。这提供了
正确的答案。
虽然它并没有完全回答您的问题,但一般的学习是它严重依赖于传递给
strptime
的格式字符串。希望这有所帮助。
as.Date.numeric
function (x, origin, ...)
{
if (missing(origin))
stop("'origin' must be supplied")
as.Date(origin, ...) + x
}
as.Date.character
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)
}
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)
}
as.Date(x = '1', format = '%j', origin= as.Date('2015-01-01'))
。请注意'1'
周围的引号。 - Rui Barradasx
时,需要使用format
,只有在x
是字符时才会考虑format
。至于origin=as.Date('2015-01-01')
,值'2015-01-01'
应自动强制转换为Date
。但实际上并没有,我认为这是一个明显的错误。 - Rui Barradas