2016-08-26 44 views
22

Mam lubridateinterval i chciałem uzyskać liczbę dni jako liczbę całkowitą. Jednak otrzymuję następujące dziwne wyniki pośrednie:Dlaczego 365 dni to 80000 lat?

library("lubridate") 
i1 <- interval("2015-01-01 00:00:00", "2016-01-01 00:00:00") 
i1 <- interval(ymd_hms("2015-01-01 00:00:00"), ymd_hms("2016-01-01 00:00:00")) # Gives the same result 
duration(i1) 
# [1] "31536000s (~365 days)" 
duration(i1, units = "days") 
# [1] "2724710400000s (~86340.86 years)" 

Oto dwa robocze skróty. Ten ostatni wyrzuca komunikat „Zmuszanie interwał czasu trwania” (i nie wiem powód, że ...)

> as.numeric(as.duration(i1), units = "days") 
[1] 365 
> as.numeric(i1, units = 'days') 

(R wersja 3.3.0 z dnia 03.05.2016, lubridate wersji 1.5. 6.)

+2

Bez znajomości 'r' w ogóle, mogę powiedzieć, że istnieją 86,400 sekundy/dzień, i zgaduj, że uzyskujesz jakąś podwójną konwersję. –

+0

Czas trwania zapisuje dane jako sekundy dla spójności. Używaj okresów, które są bardziej elastyczne w odniesieniu do jednostek: 'p1 <- as.period (i1, unit = 'days'); p1; dzień (p1) '. Zauważ, że 365 dni i 1 rok niekoniecznie są tożsame ze względu na lata przestępne, i lubridate zostało zbudowane z myślą o tym. – alistaire

Odpowiedz

27

Źle zrozumiesz znaczenie argumentu units. Z dokumentacji,

jednostek ciąg znaków, który określa rodzaj jednostek num dotyczy.

gdzie num jest pierwszym argumentem. Tak

duration(i1) 

odpowiada

duration(i1, units = "seconds") 

Jednakże

duration(i1, units = "days") 

oznacza i1 mierzy się days; stąd bardzo duża liczba.

+1

To trochę dziwne (nazwałbym to błędem), że argument 'units' powinien przesłonić jednostkę o podanej wartości. –

+0

Myślę, że to trochę mylące. Początkowo zakładałem, że "jednostki" wpłyną na wynik, zamiast na argument. – csgillespie

+0

@KonradRudolph To nie jest błąd, to funkcja! :-) Poważnie, tak właśnie jest. Jeśli sprawdzisz kod czasu trwania(), to nigdy nie odczyta jednostki jakiejkolwiek klasy i po prostu traktuje argument num jako normalny wektor. Stworzyłbym metodę dla obiektu interwałowego, ale tak się nie stało. Możesz jednak zasugerować to autorom. –

9

According to the maintainer,

[pomocą duration na obiekcie interval] powinny być dozwolone. Do konwersji użyj as.duration.

Ponadto błąd w powyższym kodzie jest już ustalona przez zabronienie wywołanie funkcji:

> duration(i1) 
Error in .duration_from_num(num, units) : 
    First argument to `duration` constructor must be character or numeric. Supplied object of class 'Interval' 
> as.duration(i1) 
[1] "31536000s (~52.14 weeks)" 
+0

wydaje się, że 'as.duration' również nie działa w ten sposób. Zobacz moją edycję. – Christoph

+0

@Christoph Nie używasz tej funkcji poprawnie, 'jak.duration' nie ma argumentu 'units', a celem funkcji nie jest kontrolowanie jednostki wyświetlania, ale po prostu przekształcenie miary na czas trwania (taki sam, jak" duration "). –

+0

Masz rację, ale jestem zdezorientowany: Chciałbym mieć czas trwania "i1" w dniach. W jaki sposób powinienem to zrobić? ('duration (i1)/24/3600' daje ' '365s (~ 6.08 minut)" 'co jest błędne.' jak. numeryczne (jak.duration (i1), jednostki = "dni") 'wykonuje zadanie , ale dlaczego potrzebuję wtedy 'duration' lub' as.duration'? – Christoph