Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 以周、月、季度和年为单位获取日期之间的差异_R_Date - Fatal编程技术网

R 以周、月、季度和年为单位获取日期之间的差异

R 以周、月、季度和年为单位获取日期之间的差异,r,date,R,Date,我有两个日期,比如说14.01.2013和26.03.2014 我想用周(?)、月(在示例14中)、季度(4)和年(1)来计算这两个日期之间的差异 你知道得到这个的最佳方法吗?试试这个解决方案 StartDate <- strptime("14 January 2013", "%d %B %Y") EventDates <- strptime(c("26 March 2014"), "%d %B %Y") difftime(EventDates, StartDate) Sta

我有两个日期,比如说
14.01.2013
26.03.2014

我想用周(?)、月(在示例14中)、季度(4)和年(1)来计算这两个日期之间的差异


你知道得到这个的最佳方法吗?

试试这个解决方案

StartDate <- strptime("14 January 2013", "%d %B %Y") 
EventDates <- strptime(c("26 March 2014"), "%d %B %Y") 
difftime(EventDates, StartDate) 
StartDate这里有一个解决方案:

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

dates对于周,您可以使用函数
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
然而,这是您的时间间隔所跨越的月数、季度数或年数,而不是以月、季度、年表示的时间间隔的持续时间(因为这些时间间隔没有固定的持续时间)。考虑到您对@SvenHohenstein答案的评论,我认为您可以使用
nlevels(cut(seq1,“months”)-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
中<代码>年份()。
你觉得怎么样?

我写这篇文章是为了另一个问题,然后在这里绊倒了

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)
}
库(lubridate)
#"算年龄",
#' 
#'默认情况下,使用
#“\code{floor}应用于您,例如,5岁
#从你5岁生日到6岁生日的前一天。设置
#“\code{floor=FALSE}返回十进制年龄,并更改\code{units}
#“对于年以外的单位。
#@param dob出生日期,开始计算年龄的日期。
#“@param age.day计算年龄的日期。
#“@param units用于测量年龄的单位。默认值为\code{“years”}。传递给\link{\code{duration}。
#“@param floor boolean用于确定是否对结果执行floor操作。默认值为\code{TRUE}。
#“@returnage in\code{units}。如果\code{floor=TRUE},则为整数。
#“@示例

#‘my.dob所有现有答案都不完善(IMO),要么对期望输出进行假设,要么没有为期望输出提供灵活性

基于OP中的例子,以及OP所陈述的预期答案,我认为这些是您正在寻找的答案(再加上一些额外的例子,使其易于推断)

(这只需要基础R,不需要zoo或lubridate)

转换为日期时间对象

date_strings = c("14.01.2013", "26.03.2014")
datetimes = strptime(date_strings, format = "%d.%m.%Y") # convert to datetime objects
# get desired output for quarters, given your definition of 'quarters'
floor(diff_in_years * 4)
#[1] 4
天数差异

date_strings = c("14.01.2013", "26.03.2014")
datetimes = strptime(date_strings, format = "%d.%m.%Y") # convert to datetime objects
# get desired output for quarters, given your definition of 'quarters'
floor(diff_in_years * 4)
#[1] 4
您可以在几天内使用diff来获得我们以后的一些答案

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

date_strings = c("14.01.2013", "26.03.2014")
datetimes = strptime(date_strings, format = "%d.%m.%Y") # convert to datetime objects
# get desired output for quarters, given your definition of 'quarters'
floor(diff_in_years * 4)
#[1] 4
周差是
difftime()

请注意,这与将我们的差异天数除以7(一周7天)相同

年份差异

date_strings = c("14.01.2013", "26.03.2014")
datetimes = strptime(date_strings, format = "%d.%m.%Y") # convert to datetime objects
# get desired output for quarters, given your definition of 'quarters'
floor(diff_in_years * 4)
#[1] 4
通过类似的逻辑,我们可以从不同的天数中得出年份

diff_in_years = as.double(diff_in_days)/365 # absolute years
diff_in_years
#[1] 1.194406
您似乎期望年差为“1”,因此我假设您只想计算绝对日历年或其他,您可以使用
floor()

季度差异

date_strings = c("14.01.2013", "26.03.2014")
datetimes = strptime(date_strings, format = "%d.%m.%Y") # convert to datetime objects
# get desired output for quarters, given your definition of 'quarters'
floor(diff_in_years * 4)
#[1] 4
月份差异

date_strings = c("14.01.2013", "26.03.2014")
datetimes = strptime(date_strings, format = "%d.%m.%Y") # convert to datetime objects
# get desired output for quarters, given your definition of 'quarters'
floor(diff_in_years * 4)
#[1] 4
可以将其计算为不同年份的换算

# 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
我知道这个问题很老了,但考虑到我现在还得解决这个问题,我想我会补充我的答案。希望能有帮助

更“精确”的计算。也就是说,非完整周/月/季/年的周/月/季/年数是该周/月/季/年中日历天数的分数。例如,2016-02-22和2016-03-31之间的月数为8/29+31/31=1.27586

与代码内联的解释

#' 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
计算两个日期之间的精确周期数 #' #“@详细说明非完整周/月/季/年的周/月/季/年数 #'是该周/月/季度/年中日历日的分数。 #例如,2016-02-22和2016-03-31之间的月数 #'是8/29+31/31=1.27586 #' #“@param startdate间隔的开始日期 #“@param enddate间隔的结束日期 #“@param句点字符。它必须是“天”、“周”、“月”、“季度”和“年”中的一个 #' #“@示例 #“完全相同(numPeriods(截至日期(“2016-02-15”)、截至日期(“2016-03-31”)、“月份”)、15/29+1) #“相同(numPeriods(截至日期(“2016-02-15”)、截至日期(“2016-03-31”)、“季度”)、(15+31)/(31+29+31)) #“相同(numPeriods(截至日期(“2016-02-15”)、截至日期(“2016-03-31”)、“年份”)、(15+31)/366) #' #“@返回介于 #'
numPeriods这里仍然缺少
lubridate
答案(尽管是基于此软件包构建的)

这对于理解时段和持续时间之间的差异非常有帮助。我也喜欢和

库(lubridate)
日期[1]“14m 12d 0H 0M 0S”
as.期间(跨度,单位='天')
#>[1]“436d 0H 0M 0S”
周期不接受周作为单位。但您可以将持续时间转换为周:

as.duration(span)/ dweeks(1)
#makes duration object (in seconds) and divides by duration of a week (in seconds)
#> [1] 62.28571

由(v0.3.0)创建于2019-11-04这是一种简单的方法,可以找出lubridate包的年份差异:

同数字(同日期(“2013年3月14日”,格式=“%d-%m-%Y”)%--%as.日期(“2014年3月23日”,格式=“%d-%m-%Y”),“年”)

返回1.023956
如果不需要小数,可以使用floor()。

谢谢,但是您的解决方案不会在所有情况下都有效。例如,如果您使用的日期仍然不准确,我建议使用365.242来表示一年中的天数,而不是365天。对于周,我发现以下difftime(time1,time2,units=“weeks”)。不幸的是,这在几个月、几个季度、几年内都不起作用。嗨,瑞秋,谢谢你,但这不起作用。当我运行strtime(“2013年1月14日,“%d%B%Y”)时,我在这里得到了相同的NA。。如果我使用这个步骤,我会发现这个解决方案只适用于英语地区。使用
%m
和数字月份(例如1月)比使用
%B
安全得多。这个答案需要小心。。。它将考虑12月31日2013吨。