r - 在 R 中寻求 as.Date() 函数的解释
问题描述
我正在将一年中的某一天转换为日期,我注意到这as.Date
通常会返回意想不到的(对我而言)结果。为什么我对这些命令得到如此不同的答案?
as.Date(x = 1, format = '%j', origin= '2015-01-01')
返回"2018-07-21"
as.Date(x = 1, origin= '2015-01-01')
返回"2015-01-02"
as.Date(x = 1, format = '%j', origin= as.Date('2015-01-01'))
返回"2015-01-02"
as.Date(x = '1',format = '%j', origin= '2015-01-01')
返回"2018-01-01"
as.Date(x = '1', origin= '2015-01-01')
返回错误:Error in charToDate(x) :
character string is not in a standard unambiguous format
解决方案
methods
我试图通过查看下的各种定义S3 generic 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')
}
在第一次调用中,UseMethod
ofas.Date
被调用,它将它分派到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
转换为. 请注意,时区可能因您所在的国家/地区而异。内部调用无法使用此过程调试的 C 函数。2018-07-20
as.Date
strptime
在第二次调用中,主要区别在于用户未提供格式字符串。因此,按照上述相同的过程,调用的是charToDate
内部定义的函数,as.Date.character
而不是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)
}
推荐阅读
- java - Java:如何禁用按钮,直到选中 1 个 RecyclerView 项目复选框?
- angular - 如何使此验证符合要求?
- ios - 防止 MKPointAnnotation 数组中出现重复的标题条目
- flutter - 如何制作一个项目网格,其中小部件彼此尽可能接近?
- javascript - 用类声明一个变量
- c# - 从 HTML 代码中获取一部分到 C# 中的字符串变量
- javascript - 在链接悬停时更改部分背景图像
- latex - hf-tikz 和 sphinx 玩得不好
- unity3d - 如何在 Unity 中将 Content Type 设置为 Integer 的 inputfield 的 int 值设置为?
- pandas - `TypeError: '<' 在 'str' 和 'int' 的实例之间不支持` Pandas