R中字符串到日期转换的"标准明确日期"格式是什么?

Mat*_*wle 81 r date strptime date-formatting as.date

请考虑以下事项

$ R --vanilla

> as.Date("01 Jan 2000")
Error in charToDate(x) :
    character string is not in a standard unambiguous format
Run Code Online (Sandbox Code Playgroud)

但是那个日期显然标准的明确格式.为什么出现错误信息?

更糟糕的是,一个模棱两可的日期显然是在没有警告或错误的情况下被接受的,然后读错了!

> as.Date("01/01/2000")
[1] "0001-01-20"
Run Code Online (Sandbox Code Playgroud)

我搜索过并在包含此错误消息的[R]标签中发现了28个其他问题.所有涉及指定格式的解决方案和解决方法,iiuc.这个问题的不同之处在于,我在问无论如何定义标准的明确格式,它们可以改变吗?每个人都得到这些消息还是仅仅是我?也许它与语言环境有关?

换句话说,有没有比需要指定格式更好的解决方案?

包含"[R]标准明确格式"的29个问题

> sessionInfo()
R version 2.15.2 (2012-10-26)
Platform: x86_64-w64-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=English_United Kingdom.1252
[2] LC_CTYPE=English_United Kingdom.1252
[3] LC_MONETARY=English_United Kingdom.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United Kingdom.1252

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base
Run Code Online (Sandbox Code Playgroud)

Jos*_*ich 60

这是记录在案的行为.来自?as.Date:

format:字符串.如果未指定,它将在第一个非'''元素上尝试'"%Y-%m-%d"'然后''%Y /%m /%d"',如果两个元素都不起作用则给出错误.

as.Date("01 Jan 2000")产生错误,因为格式不是上面列出的两种格式之一. as.Date("01/01/2000")产生错误答案,因为日期不是上面列出的两种格式之一.

我将"标准明确"改为"ISO-8601"(即使as.Date不严格,因为"%m /%d /%Y"不是ISO-8601).

如果收到此错误,解决方案是使用中描述的格式指定日期(或日期时间)的格式?strptime.如果您的数据包含日/月名称和/或缩写,请务必特别小心,因为转换将取决于您的区域设置(请参阅示例?strptime和阅读?LC_TIME).

  • 该行为肯定记录在`?as.Date`(+1)中.但是,错误信息"标准的明确格式"具有讽刺意味,前面的23个问题证明了这一点.更直接的错误消息,例如"格式无法识别,请参阅文档"可能会改善用户体验.另外,我不认为"01/01/2000"是ISO-8601("2000-01-01"是ISO-8601),这增加了歧义. (8认同)
  • @BenBolker怎么样``字符串不是%Y-%m-%d或%Y /%m /%d"`? (6认同)

Dir*_*tel 29

换句话说,有没有比需要指定格式更好的解决方案?

是的,现在有了(即2016年底),感谢anytime::anydate来自任何时间的套餐.

有关上面的一些示例,请参阅以下内容:

R> anydate(c("01 Jan 2000", "01/01/2000", "2015/10/10"))
[1] "2000-01-01" "2000-01-01" "2015-10-10"
R> 
Run Code Online (Sandbox Code Playgroud)

如你所说,这些实际上是明确无误的,应该可行.并通过anydate()他们做.没有格式.

  • 只是来到这里因为我们有另一个问题,试图用_incomplete_格式解析日期.对于完整的,我们现在有一些东西.我对此非常满意 - 这是一个令人烦恼的问题.不用说,`anytime()`对于'POSIXct`同样有用. (2认同)

pla*_*pus 25

作为@JoshuaUlrich答案的补充,这里是函数的定义as.Date.character:

as.Date.character
function (x, format = "", ...) 
{
    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) || !is.na(strptime(xx, f <- "%Y-%m-%d", 
            tz = "GMT")) || !is.na(strptime(xx, f <- "%Y/%m/%d", 
            tz = "GMT"))) 
            return(strptime(x, f))
        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)
}
<bytecode: 0x265b0ec>
<environment: namespace:base>
Run Code Online (Sandbox Code Playgroud)

所以基本上如果同时strptime(x, format="%Y-%m-%d")strptime(x, format="%Y/%m/%d")抛出NA它被认为是不明确的,如果没有明确.


小智 6

在不指定当前格式的情况下转换日期很容易给您带来此错误。

下面是一个例子:

sdate <- "2015.10.10"
Run Code Online (Sandbox Code Playgroud)

在不指定格式的情况下进行转换:

date <- as.Date(sdate4) # ==> This will generate the same error"""Error in charToDate(x): character string is not in a standard unambiguous format""".
Run Code Online (Sandbox Code Playgroud)

用指定格式转换:

date <- as.Date(sdate4, format = "%Y.%m.%d") # ==> Error Free Date Conversion.
Run Code Online (Sandbox Code Playgroud)