Проблема не в поднаборах, а в преобразовании строк даты.
Сначала , нам нужно различать внутреннее (числовое) представление даты в R и формат даты, когда она печатается в виде строки символов.
Второй , мы должны признать, что во всем мире люди пишут даты в разных форматах.Например, последний день 2017 года можно записать как
12/31/2017
12/31/17
31/12/2017
31.12.2017
31.12.17
20171231
2017/12/31
2017-12-31
(если мыучитывайте только числовые форматы).Форматы различаются в том порядке, в котором дни, месяцы и годы отображаются в строке, а также в символах, используемых для разделения записей.
К сожалению, некоторые форматы неоднозначны, т.е. вы не можете решить, какой формат былиспользуется и как интерпретировать строку даты.Например, какую дату представляет строка символов 03/04/2017
?3 апреля 2017 или 4 марта 2017?(Ситуация ухудшается, если год задается только двумя цифрами, например, 03/04/05
.)
Вот почему as.Date()
имеет параметр format
, который можно использовать, чтобы указать R, как интерпретироватьзаданная строка даты.
Однако некоторые форматы называются однозначными, поскольку R знает, как интерпретировать строку даты без дополнительной подсказки.Прежде всего, это формат даты YYYY-MM-DD
, определенный в стандарте ISO 8601 .Этот формат используется по умолчанию при печати дат, например,
Sys.Date()
[1] "2018-07-04"
При вводе as.Date()
принимает также YYYY/MM/DD
, например,
as.Date("2017/12/31")
[1] "2017-12-31"
Итак, две ваши функции можно изменить, чтобы они принимали строки даты в предпочитаемом формате, указав параметр format
:
begdate <- function()
{
n <- readline(prompt = "Enter begin date:" )
return(as.Date(n, format = "%m/%d/%Y"))
}
bdate <- begdate(); bdate
, который теперь работает, как ожидаетсядля вашего предпочтительного формата
Enter begin date:12/31/2017
[1] "2017-12-31"
, но вернет NA
в случае строк даты, которые не соответствуют указанному формату
bdate <- begdate(); bdate
Enter begin date:2017-12-31
[1] NA
С версией R 3.5.0 (выпущена 2018-04-23 для CRAN), as.Date()
получил новый параметр tryFormats
, который принимает символьный вектор из format
строк, чтобы попробовать, если format
не указано.
begdate <- function()
{
n <- readline(prompt = "Enter begin date:" )
return(as.Date(n, tryFormats = c("%Y-%m-%d", "%Y/%m/%d", "%m/%d/%Y")))
}
теперь будет правильно принимать и интерпретировать три различных формата:
Enter begin date:2017-12-31
[1] "2017-12-31"
Enter begin date:12/31/2017
[1] "2017-12-31"
Enter begin date:2017/12/31
[1] "2017-12-31"