Подтвердить что ты не робот

Каковы форматы "стандартной однозначной даты" для преобразования строки в дату в R?

Пожалуйста, рассмотрите следующие

$ 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"

Я искал и нашел еще 28 вопросов в теге [R], содержащих это сообщение об ошибке. Все с решениями и обходными решениями с указанием формата, iiuc. Этот вопрос отличается тем, что я спрашиваю, где все равно определены стандартные однозначные форматы, и можно ли их изменить? Получают ли все эти сообщения или это только я? Возможно, это связано с локалью?

Другими словами, есть ли лучшее решение, чем нужно указать формат?

29 вопросов, содержащих "стандартный нечеткий формат [R]"

> 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
4b9b3361

Ответ 1

Это документированное поведение. От ?as.Date:

format: Строка символов. Если не указано, оно попытается            "% Y-% m-% d" ', затем "% Y/% m/% d" ' на первом элементе, отличном от "NA",           и дать ошибку, если не работает.

as.Date("01 Jan 2000") дает ошибку, потому что формат не является одним из двух перечисленных выше. as.Date("01/01/2000") дает неправильный ответ, потому что дата не находится в одном из двух форматов, перечисленных выше.

Я принимаю "стандартное однозначное" значение "ISO-8601" (хотя as.Date не является строгим, поскольку "% m/% d/% Y" не является ISO-8601).

Если вы получили эту ошибку, решение должно указать формат даты (или даты), используя форматы, описанные в ?strptime. Обязательно используйте особую осторожность, если ваши данные содержат имена дня и месяца и/или аббревиатуры, поскольку преобразование будет зависеть от вашего языка (см. Примеры в ?strptime и прочитать ?LC_TIME).

Ответ 2

В качестве дополнения к ответу @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, это считается неоднозначным и если не однозначным.

Ответ 3

Другими словами, есть ли лучшее решение, чем нужно указать формат?

Да, сейчас (т.е. в конце 2016 года), благодаря anytime::anydate из anytime.

Ниже приведено несколько примеров:

R> anydate(c("01 Jan 2000", "01/01/2000", "2015/10/10"))
[1] "2000-01-01" "2000-01-01" "2015-10-10"
R> 

Как вы сказали, они на самом деле однозначны и должны просто работать. И через anydate() они делают. Без формата.

Ответ 4

Преобразование даты без указания текущего формата может легко донести эту ошибку.

Вот пример:

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.

Ответ 5

Это прекрасно работает для меня, независимо от того, как дата была закодирована ранее.

library(lubridate)
data$created_date1 <- mdy_hm(data$created_at)
data$created_date1 <- as.Date(data$created_date1)