107

请考虑以下

$ R --vanilla

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

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

更糟糕的是,一个模棱两可的日期显然被接受而没有警告或错误,然后读取不正确!

> as.Date("01/01/2000")
[1] "0001-01-20"

我在包含此错误消息的 [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
4

7 回答 7

71

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

格式:一个字符串。如果未指定,它将在第一个非 'NA' 元素上尝试 '"%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;另请参阅strptimeas.POSIXctas.Date返回意外NA)。

于 2013-02-07T16:10:55.000 回答
38

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

是的,现在有(即 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> 

正如你所说,这些实际上是明确的,应该可以工作。并且通过anydate()他们这样做。没有格式。

于 2016-11-20T21:32:25.790 回答
27

作为@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>

所以基本上如果两者都strptime(x, format="%Y-%m-%d")抛出strptime(x, format="%Y/%m/%d")一个NA它被认为是模棱两可的,如果不是明确的。

于 2013-02-07T16:19:41.410 回答
6

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

这是一个例子:

sdate <- "2015.10.10"

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

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

以指定格式转换:

date <- as.Date(sdate4, format = "%Y.%m.%d") # ==> Error Free Date Conversion.
于 2015-12-19T20:42:44.453 回答
4

这对我来说非常有效,无论日期之前是如何编码的。

library(lubridate)
data$created_date1 <- mdy_hm(data$created_at)
data$created_date1 <- as.Date(data$created_date1)
于 2019-06-07T00:56:18.073 回答
2

作为补充:如果您尝试转换的条目是应该是 NA 的字符串,也会引发此错误。如果您指定预期格式 - 或使用“真实” NA - 没有问题:

data.table 的最小可重现示例:

library(data.table)
df <- data.table(date_good = c("01-01-2001", "01-01-2001"), date_bad= ("NA", "01-01-2001"))

df[, .(date_good = as.Date(date_good), date_bad = as.Date(date_bad))]
# Error in charToDate(x) : character string is not in a standard unambiguous format

df[, .(date_good = as.Date(date_good), date_bad = as.Date(date_bad, format="%Y-%m-%d"))]
# No errors; you simply get NA.

df2 <- data.table(date_good = c("01-01-2001", "01-01-2001"), date_bad= (NA, "01-01-2001"))
    
df2[, .(date_good = as.Date(date_good), date_bad = as.Date(date_bad))]
# Just NA
于 2021-08-04T21:13:57.217 回答
0

如果日期是例如:“2000 年 1 月 1 日”,我建议使用

library(lubridate)
date_corrected<-dmy("01 Jan 2000")
date_corrected
[1] "2000-01-01"
class(date_corrected)
[1] "Date"

lubridate 对几乎所有类型的日期都有一个功能。

于 2021-07-12T20:55:39.413 回答