Erhalten Sie den Unterschied zwischen Daten in Wochen, Monaten, Quartalen und Jahren

Ich habe zwei Termine, sagen wir 14.01.2013 und 26.03.2014 .

Ich möchte die Differenz zwischen diesen beiden Daten in Wochen (?), Monaten (in Beispiel 14), Quartalen (4) und Jahren (1) unterscheiden.

Kennen Sie den besten Weg, um das zu bekommen?

   

Was ist damit?

 # 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() und as.yearqtr() sind im Paket zoo . year() ist im Paket lubridate . Was denken Sie?

Alle vorhandenen Antworten sind unvollständig (IMO) und machen entweder Annahmen über die gewünschte Ausgabe oder bieten keine Flexibilität für die gewünschte Ausgabe.

Auf der Grundlage der Beispiele aus dem OP und der erklärten erwarteten Antworten des OPs sind dies die Antworten, nach denen Sie suchen (und einige zusätzliche Beispiele, die eine Extrapolation erleichtern).

(Dies erfordert nur Base R und benötigt keinen Zoo oder Lubridat)

In Datetime-Objekte konvertieren

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

Differenz in Tagen

Sie können den Diff in Tagen verwenden, um einige unserer späteren Antworten zu erhalten

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

Unterschied in Wochen

Der Unterschied in Wochen ist ein Sonderfall von units = "weeks" in difftime()

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

Beachten Sie, dass dies das Gleiche ist wie das Teilen von diff_in_days mit 7 (7 Tage in der Woche)

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

Unterschied in Jahren

Mit ähnlicher Logik können wir Jahre von diff_in_days ableiten

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

Sie scheinen zu erwarten, dass der Unterschied in Jahren “1” ist, also nehme ich an, dass Sie nur absolute Kalenderjahre oder etwas zählen wollen, was Sie leicht mit floor() tun können.

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

Unterschied in den Quartalen

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

Unterschied in Monaten

Kann dies als eine Konvertierung von diff_years berechnen

 # 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 

Ich weiß, dass diese Frage alt ist, aber angesichts dessen, dass ich dieses Problem gerade erst lösen musste, dachte ich, ich würde meine Antworten hinzufügen. Ich hoffe es hilft.

Seit Wochen können Sie die function 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 

Aber difftime funktioniert nicht mit der Dauer über Wochen.
Das Folgende ist eine sehr suboptimale Lösung mit cut.POSIXt für diese Zeit, aber Sie können es cut.POSIXt :

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

Dies ist jedoch die Anzahl der Monate, Quartale oder Jahre, die Ihr Zeitintervall umfasst, und nicht die Dauer Ihres Zeitintervalls, ausgedrückt in Monaten, Quartalen, Jahren (da diese keine konstante Dauer haben). In Anbetracht des Kommentars, den du auf @SvenHohenstein geantwortet hast, würde ich denken, du kannst nlevels(cut(seq1,"months")) - 1 für das verwenden, was du erreichen willst.

Ich habe das nur für eine andere Frage geschrieben und bin dann hier gestolpert.

 library(lubridate) #' Calculate age #' #' By default, calculates the typical "age in years", with a #' \code{floor} applied so that you are, eg, 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) } 

Anwendungsbeispiele:

 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 

Hier ist eine Lösung:

 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 

Versuchen Sie dies für eine monatelange Lösung

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

Eine “genauere” Berechnung. Das heißt, die Anzahl der Woche / Monat / Quartal / Jahr für eine nicht vollständige Woche / Monat / Quartal / Jahr ist der Bruchteil der Kalendertage in dieser Woche / Monat / Quartal / Jahr. Zum Beispiel ist die Anzahl der Monate zwischen 2016-02-22 und 2016-03-31 8/29 + 31/31 = 1,27586

Erklärung inline mit 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 

Bitte lassen Sie mich wissen, wenn Sie weitere Grenzfälle finden, in denen die obige Lösung nicht funktioniert.