2013-03-22 2 views
13

Я хочу исправить исходную активность на основе разницы между эталонной датой измерения и временем полужизни источника (измеряется в годах). Скажем, у меня естьR получить разницу дат в годах (с плавающей запятой)

ref_date <- as.Date('06/01/08',format='%d/%m/%y') 

и столбец в моем data.frame с такой же формат даты, например,

today <- as.Date(Sys.Date(), format='%d/%m/%y') 

я могу найти количество лет между этими датами, используя lubridate пакет

year(today)-year(ref_date) 
[1] 5 

Есть функция, которую я могу использовать для получения ответа с плавающей запятой today - ref_date = 5.2y, например?

ответ

23

Да, конечно, использовать difftime() с, как числовая:

R> as.numeric(difftime(as.Date("2003-04-05"), as.Date("2001-01-01"), 
+      unit="weeks"))/52.25 
[1] 2.2529 
R> 

Обратите внимание, что мы должны переключиться на недель масштабируемых по 52.25, поскольку есть немного двусмысленности там с точки зрения подсчета лет- - 29 февраля происходит каждые 4 года, но не каждые 100 и т. д.

Значит, вы должны это определить. difftime() обрабатывает все единицы времени до нескольких недель. Месяцы не могут быть выполнены по той же причине непостоянного «числителя».

+0

Спасибо. Я предполагаю, что могу делить на 365.25 и пропустить «unit = weeks» – moadeep

+1

Нет, вам нужно - просто поиграть с ним, чтобы видеть. Блок автоматически настраивает, пробует его с дельтами менее одного или даже с объектами POSIXct (например, из 'Sys.time()') –

+0

И недели всегда одинакового числа за год? – sop

-1

Поскольку вы уже используете пакет lubridate, вы можете получить несколько лет с плавающей точкой, используя простой трюк:

найти количество секунд, в течение одного года:

seconds_in_a_year <- as.integer((seconds(ymd("2010-01-01")) - seconds(ymd("2009-01-01")))) 

Получит теперь количество секунд между 2 датами вы хотите

seconds_between_dates <- as.integer(seconds(date1) - seconds(date2)) 

окончательного ответа на количество лет в плавающих точках будут

years_between_dates <- seconds_between_dates/seconds_in_a_year 
1

Неточный ответ на ваш вопрос, но ответ от Dirk Eddelbuettel в некоторых ситуациях может привести к небольшим ошибкам.

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

as.numeric(difftime(as.Date("2012-03-01"), as.Date("2017-03-01"), unit="weeks"))/52.25 
[1] -4.992481 

Правильный ответ здесь должен быть не менее 5 лет.

Следующая функция (с использованием lubridate пакета) рассчитает количество полных лет между двумя датами:

# Function to calculate an exact full number of years between two dates 
year.diff <- function(firstDate, secondDate) { 
    yearsdiff <- year(secondDate) - year(firstDate) 
    monthsdiff <- month(secondDate) - month(firstDate) 
    daysdiff <- day(secondDate) - day(firstDate) 

    if ((monthsdiff < 0) | (monthsdiff == 0 & daysdiff < 0)) { 
    yearsdiff <- yearsdiff - 1 
    } 

    yearsdiff 
} 

Вы можете изменить его, чтобы вычислить дробную часть в зависимости от того, как вы определяете количество дней в последний (не законченный) год.

1

lubridate пакет содержит встроенную функцию, TIME_LENGTH, который может помочь выполнить эту задачу.

time_length(difftime(as.Date("2003-04-05"), as.Date("2001-01-01")), "years") 
[1] 2.257534 

time_length(difftime(as.Date("2017-03-01"), as.Date("2012-03-01")),"years") 
[1] 5.00274 

Документацию для lubridate пакета можно найти here.

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