code

주, 월, 분기 및 연도 측면에서 날짜 간의 차이를 가져옵니다.

codestyles 2020. 12. 7. 08:11
반응형

주, 월, 분기 및 연도 측면에서 날짜 간의 차이를 가져옵니다.


나는 두 날짜 let's 말을 14.01.2013하고 26.03.2014.

주 (?), 월 (예제 14), 분기 (4) 및 연도 (1) ​​측면에서이 두 날짜의 차이를 얻고 싶습니다.

이것을 얻는 가장 좋은 방법을 알고 있습니까?


이것에 대해 :

# get difference between dates `"01.12.2013"` and `"31.12.2013"`

# weeks
difftime(strptime("26.03.2014", format = "%d.%m.%Y"),
strptime("14.01.2013", format = "%d.%m.%Y"),units="weeks")
Time difference of 62.28571 weeks

# months
(as.yearmon(strptime("26.03.2014", format = "%d.%m.%Y"))-
as.yearmon(strptime("14.01.2013", format = "%d.%m.%Y")))*12
[1] 14

# quarters
(as.yearqtr(strptime("26.03.2014", format = "%d.%m.%Y"))-
as.yearqtr(strptime("14.01.2013", format = "%d.%m.%Y")))*4
[1] 4

# years
year(strptime("26.03.2014", format = "%d.%m.%Y"))-
year(strptime("14.01.2013", format = "%d.%m.%Y"))
[1] 1

as.yearmon()그리고 as.yearqtr()패키지에 zoo있습니다. year()패키지에 lubridate있습니다. 어떻게 생각해?


기존의 모든 답변은 불완전하며 (IMO) 원하는 출력에 대해 가정하거나 원하는 출력에 대한 유연성을 제공하지 않습니다.

OP의 예와 OP의 명시된 예상 답변을 기반으로, 이것이 당신이 찾고있는 답변이라고 생각합니다 (외삽하기 쉬운 추가 예 포함).

(베이스 R 만 필요하며 동물원이나 윤활유가 필요하지 않습니다)

Datetime 객체로 변환

date_strings = c("14.01.2013", "26.03.2014")
datetimes = strptime(date_strings, format = "%d.%m.%Y") # convert to datetime objects

일수 차이

며칠 안에 diff를 사용하여 나중에 답변을 얻을 수 있습니다.

diff_in_days = difftime(datetimes[2], datetimes[1], units = "days") # days
diff_in_days
#Time difference of 435.9583 days

주 차이

주 차이는 특별한 경우입니다 units = "weeks".difftime()

diff_in_weeks = difftime(datetimes[2], datetimes[1], units = "weeks") # weeks
diff_in_weeks
#Time difference of 62.27976 weeks

이것은 diff_in_days를 7로 나누는 것과 같습니다 (1 주일에 7 일).

as.double(diff_in_days)/7
#[1] 62.27976

연도의 차이

비슷한 논리로 diff_in_days에서 연도를 도출 할 수 있습니다.

diff_in_years = as.double(diff_in_days)/365 # absolute years
diff_in_years
#[1] 1.194406

연도의 차이가 "1"이 될 것으로 예상하는 것 같습니다. 따라서 절대 달력 연도 등을 계산하기를 원한다고 가정합니다. floor()

# get desired output, given your definition of 'years'
floor(diff_in_years)
#[1] 1

분기 차이

# get desired output for quarters, given your definition of 'quarters'
floor(diff_in_years * 4)
#[1] 4

달의 차이

이것을 diff_years의 변환으로 계산할 수 있습니다.

# months, defined as absolute calendar months (this might be what you want, given your question details)
months_diff = diff_in_years*12
floor(month_diff)
#[1] 14

이 질문이 오래되었다는 것을 알고 있지만 지금 당장이 문제를 해결해야했기 때문에 답변을 추가 할 것이라고 생각했습니다. 도움이 되었기를 바랍니다.


몇 주 동안 함수를 사용할 수 있습니다 difftime.

date1 <- strptime("14.01.2013", format="%d.%m.%Y")
date2 <- strptime("26.03.2014", format="%d.%m.%Y")
difftime(date2,date1,units="weeks")
Time difference of 62.28571 weeks

그러나 difftime몇 주에 걸친 기간에서는 작동하지 않습니다.
다음은 cut.POSIXt이러한 기간 동안 사용하는 매우 차선책 이지만 해결할 수 있습니다.

seq1 <- seq(date1,date2, by="days")
nlevels(cut(seq1,"months"))
15
nlevels(cut(seq1,"quarters"))
5
nlevels(cut(seq1,"years"))
2

그러나 이것은 시간 간격에 포함 된 월, 분기 또는 년의 수이며 월, 분기, 년으로 표시되는 시간 간격의 기간이 아닙니다 (일정 기간이 없기 때문에). @SvenHohenstein 답변에 대한 의견을 고려할 때 nlevels(cut(seq1,"months")) - 1달성하려는 것을 사용할 수 있다고 생각합니다 .


나는 다른 질문을 위해 이것을 썼다가 여기서 우연히 발견되었습니다.

library(lubridate)

#' Calculate age
#' 
#' By default, calculates the typical "age in years", with a
#' \code{floor} applied so that you are, e.g., 5 years old from
#' 5th birthday through the day before your 6th birthday. Set
#' \code{floor = FALSE} to return decimal ages, and change \code{units}
#' for units other than years.
#' @param dob date-of-birth, the day to start calculating age.
#' @param age.day the date on which age is to be calculated.
#' @param units unit to measure age in. Defaults to \code{"years"}. Passed to \link{\code{duration}}.
#' @param floor boolean for whether or not to floor the result. Defaults to \code{TRUE}.
#' @return Age in \code{units}. Will be an integer if \code{floor = TRUE}.
#' @examples
#' my.dob <- as.Date('1983-10-20')
#' age(my.dob)
#' age(my.dob, units = "minutes")
#' age(my.dob, floor = FALSE)
age <- function(dob, age.day = today(), units = "years", floor = TRUE) {
    calc.age = interval(dob, age.day) / duration(num = 1, units = units)
    if (floor) return(as.integer(floor(calc.age)))
    return(calc.age)
}

사용 예 :

my.dob <- as.Date('1983-10-20')

age(my.dob)
# [1] 31

age(my.dob, floor = FALSE)
# [1] 31.15616

age(my.dob, units = "minutes")
# [1] 16375680

age(seq(my.dob, length.out = 6, by = "years"))
# [1] 31 30 29 28 27 26

해결책은 다음과 같습니다.

dates <- c("14.01.2013", "26.03.2014")

# Date format:
dates2 <- strptime(dates, format = "%d.%m.%Y")

dif <- diff(as.numeric(dates2)) # difference in seconds

dif/(60 * 60 * 24 * 7) # weeks
[1] 62.28571
dif/(60 * 60 * 24 * 30) # months
[1] 14.53333
dif/(60 * 60 * 24 * 30 * 3) # quartes
[1] 4.844444
dif/(60 * 60 * 24 * 365) # years
[1] 1.194521

A more "precise" calculation. That is, the number of week/month/quarter/year for a non-complete week/month/quarter/year is the fraction of calendar days in that week/month/quarter/year. For example, the number of months between 2016-02-22 and 2016-03-31 is 8/29 + 31/31 = 1.27586

explanation inline with code

#' Calculate precise number of periods between 2 dates
#' 
#' @details The number of week/month/quarter/year for a non-complete week/month/quarter/year 
#'     is the fraction of calendar days in that week/month/quarter/year. 
#'     For example, the number of months between 2016-02-22 and 2016-03-31 
#'     is 8/29 + 31/31 = 1.27586
#' 
#' @param startdate start Date of the interval
#' @param enddate end Date of the interval
#' @param period character. It must be one of 'day', 'week', 'month', 'quarter' and 'year'
#' 
#' @examples 
#' identical(numPeriods(as.Date("2016-02-15"), as.Date("2016-03-31"), "month"), 15/29 + 1)
#' identical(numPeriods(as.Date("2016-02-15"), as.Date("2016-03-31"), "quarter"), (15 + 31)/(31 + 29 + 31))
#' identical(numPeriods(as.Date("2016-02-15"), as.Date("2016-03-31"), "year"), (15 + 31)/366)
#' 
#' @return exact number of periods between
#' 
numPeriods <- function(startdate, enddate, period) {

    numdays <- as.numeric(enddate - startdate) + 1
    if (grepl("day", period, ignore.case=TRUE)) {
        return(numdays)

    } else if (grepl("week", period, ignore.case=TRUE)) {
        return(numdays / 7)
    }

    #create a sequence of dates between start and end dates
    effDaysinBins <- cut(seq(startdate, enddate, by="1 day"), period)

    #use the earliest start date of the previous bins and create a breaks of periodic dates with
    #user's period interval
    intervals <- seq(from=as.Date(min(levels(effDaysinBins)), "%Y-%m-%d"), 
        by=paste("1",period), 
        length.out=length(levels(effDaysinBins))+1)

    #create a sequence of dates between the earliest interval date and last date of the interval
    #that contains the enddate
    allDays <- seq(from=intervals[1],
        to=intervals[intervals > enddate][1] - 1,
        by="1 day")

    #bin all days in the whole period using previous breaks
    allDaysInBins <- cut(allDays, intervals)

    #calculate ratio of effective days to all days in whole period
    sum( tabulate(effDaysinBins) / tabulate(allDaysInBins) )
} #numPeriods

Please let me know if you find more boundary cases where the above solution does not work.


try this for a months solution

StartDate <- strptime("14 January 2013", "%d %B %Y") 
EventDates <- strptime(c("26 March 2014"), "%d %B %Y") 
difftime(EventDates, StartDate) 

참고URL : https://stackoverflow.com/questions/14454476/get-the-difference-between-dates-in-terms-of-weeks-months-quarters-and-years

반응형