2016-09-12 5 views
1

У меня возникли проблемы с работой функции as.Date в R. У меня есть вектор дат, которые я читаю из. CSV-файла, который входит как фактор целых чисел или как символ (в зависимости от как я читаю в файле, но это, похоже, не имеет ничего общего с проблемой), отформатирован как %m/%d/%Y.Почему as.Date возвращается как тип double?

Я иду через файл построчно, вытаскивая поле даты и пытается преобразовать его для использования в других местах, используя следующий код:

tmpDtm<-as.Date(as.character(tempDF$myDate), "%m/%d/%Y") 

Это, кажется, чтобы дать мне то, что я хочу, для Например, если я делаю это с начальным значением 12/30/2014, я получаю значение "2014-12-30". Однако, если я исследую это значение с помощью typeof(), R говорит мне, что его тип данных «double». Кроме того, если я попытаюсь связать это с другими значениями и сохранить его в кадре данных с использованием c() или cbind(), то в кадре данных он будет храниться как 16434, что выглядит как какое-то другое значение внутренней памяти Дата. Я уверен, что это так, потому что, если я попытаюсь снова преобразовать это значение, используя as.Date(), он выдает ошибку с запросом о происхождении.

Итак, два вопроса: это так, как ожидалось? Если это так, есть ли более подходящий способ конвертировать дату, чтобы на самом деле я получил объект с типом даты?

Спасибо

+0

Пожалуйста, сделайте воспроизводимый пример Какого типа имеют данные, которые вы 'с()' или 'cbind()' это ли вам известно, что все элементы вектора? должны быть одного типа? – Bernhard

+0

Мне это известно. Мои извинения за неясность, но тип данных двойной, прежде чем я даже попытаюсь связать (т. Е. Объект tmpDtm выше имеет тип: double). Проблема привязки для меня меньше беспокоит - если я могу убедиться, что у меня есть объект даты перед связыванием, я могу выяснить, как связать его с другими данными так, как мне нужно, - я просто подумал, что дополнительная информация может помочь в определении того, что происходит с преобразованием, прежде чем я свяжусь. – drRussClay

+0

Я лично не знаю тонких различий между двумя функциями, но попробуйте 'class' вместо' typeof'. Первый, кажется, возвращает 'Date', а последний возвращает' double'. – dsaxton

ответ

5

Даты внутренне представлены как двойной, как вы можете видеть в следующем примере:

> typeof(as.Date("09/12/16", "%m/%d/%y")) 
[1] "double" 

он по-прежнему отмечен класс Дата, как в

> class(as.Date("09/12/16", "%m/%d/%y")) 
[1] "Date" 

и поскольку он является двойным, вы можете делать с ним вычисления. Но так как он имеет класс Date, эти вычисления приводят к Дате:

> as.Date("09/12/16", "%m/%d/%y") + 1 
[1] "2016-09-13" 
> as.Date("09/12/16", "%m/%d/%y") + 31 
[1] "2016-10-13" 

EDIT Я попросил c() и cbind(), потому что они могут быть assciated с каким-то странным поведением. Смотрите следующий пример, в котором переключение заказа в течение c изменений не типа, но класс результата:

> c(as.Date("09/12/16", "%m/%d/%y"), 1) 
[1] "2016-09-12" "1970-01-02" 
> c(1, as.Date("09/12/16", "%m/%d/%y")) 
[1]  1 17056 

> class(c(as.Date("09/12/16", "%m/%d/%y"), 1)) 
[1] "Date" 
> class(c(1, as.Date("09/12/16", "%m/%d/%y"))) 
[1] "numeric" 

EDIT 2 - c() и cbind объектов заставляют быть одного типа. Первое редактирование показывает аномалию принуждения, но, как правило, вектор должен иметь один общий тип. cbind разделяет это поведение, потому что оно приводит к матрице, которая, в свою очередь, приводит к одному типу.

Для получения дополнительной помощи по typeof и class см

+0

Проверьте 'методы (« c »)'. В S3-системе класс первого аргумента определяет, какой метод используется. И как 'c', так и' cbind' являются генериками S3. Если вы хотите иметь тот же результат независимо от порядка, вам нужно будет использовать классы S4, которые могут выполнять отправку метода в зависимости от подписи всех аргументов. – Roland

2

Это, как и ожидалось.Вы использовали typeof(); Вы, вероятно, должны использоваться class():

R> Sys.Date() 
[1] "2016-09-12" 
R> typeof(Sys.Date())  # this more or less gives you how it is stored 
[1] "double" 
R> class(Sys.Date())  # where as this gives you _behaviour_ 
[1] "Date" 
R> 

Minor реклама: У меня есть новый пакет anytime, в настоящее время входящий в CRAN, которая занимается этим, как он преобразует «ничего» в POSIXct (через anytime()) или Date (через anydate() .

Например:.

R> anydate("12/30/2014")    # no format needed 
[1] "2014-12-30" 
R> anydate(as.factor("12/30/2014")) # converts from factor too 
[1] "2014-12-30" 
R> 
+1

с нетерпением жду 'в любое время! – SymbolixAU

+1

Сейчас на CRAN :) –