2015-03-23 3 views
0

Извините, у меня нет воспроизводимого примера здесь.Вычитание дат - разница в часах и секундах?

Может ли кто-нибудь объяснить или угадать, почему одно из этих различий происходит через наши дни, а другое в секундах?

> str(dat) 
$ Date.Of.Visit   : chr "2010-02-11" "2010-05-13" "2012-10-16" "2014-03-24" ... 
$ Date.Diagnosed   : chr "2003-08-23" "2003-08-23" "2003-08-23" NA ... 
$ Date.Of.Birth   : chr "1992-01-19" "1992-01-19" "1992-01-19" NA ... 

Все выглядит одинаково.

dat$Date.Of.Visit <- ymd(dat$Date.Of.Visit) 
dat$Date.Diagnosed <- ymd(dat$Date.Diagnosed) 
dat$Date.Of.Birth <- ymd(dat$Date.Of.Birth) 

Все передаются через ту же функцию lubridate.

> class(dat$Date.Of.Visit) 
[1] "POSIXct" "POSIXt" 
> class(dat$Date.Of.Birth) 
[1] "POSIXct" "POSIXt" 
> class(dat$Date.Diagnosed) 
[1] "POSIXct" "POSIXt" 

Все выглядит одинаково.

> (dat$Date.Of.Visit - dat$Date.Of.Birth)[1:10] 
Time differences in days 
[1] 6598 6689 7576 NA 3043 3141 3218 6784 4813 4974 

> (dat$Date.Diagnosed - dat$Date.Of.Birth)[1:10] 
Time differences in secs 
[1] 365817600 365817600 365817600  NA 256003200 256003200 256003200 243302400 194486400 194486400 

Единственное, что я могу думать, Date.Of.Visit завершена, Date.Of.Birth и Date.Diagnosed есть несколько пятен недостающих данных.

ответ

1

Затрудняюсь ответить окончательно без исходной информации, но посмотрите на код difftime, который используется для вычитания POSIXct объектов:

> difftime 
function (time1, time2, tz, units = c("auto", "secs", "mins", 
    "hours", "days", "weeks")) 
{ 
    if (missing(tz)) { 
     time1 <- as.POSIXct(time1) 
     time2 <- as.POSIXct(time2) 
    } 
    else { 
     time1 <- as.POSIXct(time1, tz = tz) 
     time2 <- as.POSIXct(time2, tz = tz) 
    } 
    z <- unclass(time1) - unclass(time2) 
    attr(z, "tzone") <- NULL 
    units <- match.arg(units) 
    if (units == "auto") { 
     if (all(is.na(z))) 
      units <- "secs" 
     else { 
      zz <- min(abs(z), na.rm = TRUE) 
      if (is.na(zz) || zz < 60) 
       units <- "secs" 
      else if (zz < 3600) 
       units <- "mins" 
      else if (zz < 86400) 
       units <- "hours" 
      else units <- "days" 
     } 
    } 
    switch(units, secs = .difftime(z, units = "secs"), mins = .difftime(z/60, 
     units = "mins"), hours = .difftime(z/3600, units = "hours"), 
     days = .difftime(z/86400, units = "days"), weeks = .difftime(z/(7 * 
      86400), units = "weeks")) 
} 

Так что, если any(is.na(z)) или min(abs(z), na.rm = TRUE) < 60 удовлетворяется вычитанием, так как вы не указали units, то единицы будут вынуждены секунд. Например:

> difftime("2014-03-24", c(NA,NA,NA)) 
Time differences in secs 
[1] NA NA NA 

> difftime("2014-03-24", c('2010-01-01',NA,NA)) 
Time differences in days 
[1] 1542.958  NA  NA 

> difftime("2014-03-24", c('2010-01-01','2014-03-24',NA)) 
Time differences in secs 
[1] 133311600   0  NA 

Наиболее вероятным виновником является то, что где-то разница между Date.Diagnosed и Date.Of.Birth менее чем за минуту - на основании того, что вы вставили здесь, ни один из этих векторов содержит только NA значения, какие правила выключите переключатель all(is.na(z)).

+1

И, конечно же, решение должно использовать 'diffftime' явно (с указанным модулем) вместо' -.POSIXt'. – Roland

Смежные вопросы