2010-01-03 148 views

回答

37

我正要說,很簡單,但在周difftime()停止。多麼奇怪。

所以,一個可能的答案是破解的東西了:

# turn a date into a 'monthnumber' relative to an origin 
R> monnb <- function(d) { lt <- as.POSIXlt(as.Date(d, origin="1900-01-01")); \ 
          lt$year*12 + lt$mon } 
# compute a month difference as a difference between two monnb's 
R> mondf <- function(d1, d2) { monnb(d2) - monnb(d1) } 
# take it for a spin 
R> mondf(as.Date("2008-01-01"), Sys.Date()) 
[1] 24 
R> 

比較合適。人們可以把它包裝成一些簡單的類結構。或者把它作爲一個黑客:)

編輯:也似乎與你的例子來自MathWorks的工作:

R> mondf("2000-05-31", "2000-06-30") 
[1] 1 
R> mondf(c("2002-03-31", "2002-04-30", "2002-05-31"), "2002-06-30") 
[1] 3 2 1 
R> 

添加EndOfMonth標誌作爲練習留給讀者:)

編輯2:也許difftime離開它,因爲沒有可靠的方式來表達分數差異,這將與其他單位的difftime行爲一致。

+0

謝謝,德克。 這是一個聰明的把戲。 說到單位,我發現這也是有效的.. > as.numeric(as.Date('2009-10-1') - as.Date('2009-8-01'),units = 'days') > as.numeric(as.Date('2009-10-1') - as.Date('2009-8-01'),units ='days') 但它在'周'以及。 – knguyen 2010-01-04 00:18:25

+0

我認爲這只是巧妙的重載 - 運算符來調用相同的'difftime()'函數。俗話說「沒有免費的午餐」:) – 2010-01-04 00:28:33

5

在R-Help郵件列表中有一條類似於你的消息(之前我提到過一個CRAN列表)。

這裏the link。有兩個建議的解決方案:

  • 有每月365.25/12天平均所以下面的表達式給出了D1和D2之間的月數:
#test data 
d1 <- as.Date("01 March 1950", "%d %B %Y")  
d2 <- as.Date(c("01 April 1955", "01 July 1980"), "%d %B %Y") 
# calculation 
round((d2 - d1)/(365.25/12)) 
  • 另一種可能性是得到這樣的長度seq.Dates
as.Date.numeric <- function(x) structure(floor(x+.001), class = "Date") 
sapply(d2, function(d2) length(seq(d1, as.Date(d2), by = "month")))-1 
+0

這將是R-Help郵件列表。 CRAN是一個軟件包存儲庫。 – Sharpie 2010-01-04 01:33:33

30

一個簡單的功能...

elapsed_months <- function(end_date, start_date) { 
    ed <- as.POSIXlt(end_date) 
    sd <- as.POSIXlt(start_date) 
    12 * (ed$year - sd$year) + (ed$mon - sd$mon) 
} 

例...

>Sys.time() 
[1] "2014-10-29 15:45:44 CDT" 
>elapsed_months(Sys.time(), as.Date("2012-07-15")) 
[1] 27 
>elapsed_months("2002-06-30", c("2002-03-31", "2002-04-30", "2002-05-31")) 
[1] 3 2 1 

對我來說是有意義的思考這個問題簡單地減去兩個日期,以及因爲minuend − subtrahend = difference (wikipedia),我把第一個更晚的日期放在參數列表中。

注意,它工作正常的日期,儘管有一年的內部表示這些日期爲陰性前述1900年,得益於規則減去負數...

> elapsed_months("1791-01-10", "1776-07-01") 
[1] 174 
24

有可能是一個更簡單的方法。這不是一個功能,但它只是一條線。

length(seq(from=date1, to=date2, by='month')) - 1 

例如,

> length(seq(from=Sys.Date(), to=as.Date("2020-12-31"), by='month')) - 1 

產地:

[1] 69 

這種計算兩個日期之間的整月數。如果要包含當前月份/餘額不是整個月份,請刪除-1。

+1

這是一個好主意,謝謝Dominic – Victor 2015-11-26 21:44:02

+1

這並不總是給出預期的結果。 'length(seq(from = as.Date(「2015-01-31」),to = as.Date(「2015-03-31」),by ='month'))= 3' 此外, 'length(seq(from = as.Date(「2015-01-31」),to = as.Date(「2015-04-30」),by ='month'))= 3' – Octave1 2017-08-18 12:57:03

4
library(lubridate) 

案例1:天真功能

mos<-function (begin, end) { 
     mos1<-as.period(interval(ymd(begin),ymd(end))) 
     mos<[email protected]*[email protected] 
     mos 
} 

案例2:如果您需要考慮的只是 '月',無論是 '天'

mob<-function (begin, end) { 
     begin<-paste(substr(begin,1,6),"01",sep="") 
     end<-paste(substr(end,1,6),"01",sep="") 
     mob1<-as.period(interval(ymd(begin),ymd(end))) 
     mob<[email protected]*[email protected] 
     mob 
} 

例子:

mos(20150101,20150228) # 1 
mos(20150131,20150228) # 0 
# you can use "20150101" instead of 20150101 

mob(20150131,20150228) # 1 
mob(20150131,20150228) # 1 
# you can use a format of "20150101", 20150101, 201501 
+0

interval(mdy (20150101),mdy(20150228))%/%months(1) 只需使用lubridate的本機函數間隔即可。 – mtelesha 2017-09-19 17:35:03

+0

謝謝你mtelesha。 但是,在我的業務中,我需要經常計算2天的「月計數」。 例如,20150131和20150201之間的月份必須是1. 因此,我曾經使用'mob'用戶定義函數。 你知道如何使用lubridate做到這一點嗎? – 2017-09-26 06:08:51

+0

我想你可以使用月(ymd) - 月(ymd)。或者你可以爲年,月和日製作三列。 – mtelesha 2017-09-26 22:53:38

12

我認爲這是對這個問題的更接近的答案問平價計算與MathWorks的功能

MathWorks的月功能

MyMonths = months(StartDate, EndDate, EndMonthFlag) 

我的R代碼裏面

library(lubridate) 
interval(mdy(10012015), today()) %/% months(1) 

輸出(當代碼是在2016年4月運行的)

[1] 6 

Lubridat e [包]提供的工具可以更輕鬆地解析和處理日期。這些工具按照通用目的分組。有關每個功能的更多信息,請參閱其幫助文檔。

interval {lubridate}用指定的開始和結束日期創建一個Interval-class對象。如果開始日期在結束日期之前發生,則間隔將爲正值。否則,將是負面的

今天

{lubridate}當前日期

{基本}提取一個月,這些都是通用的功能:爲內部日期時間類中的方法都記錄這裏。

%/%{鹼}指示整數除法AKA(X%/%Y)(最多舍入誤差)

3
library(lubridate) 
date1 = "1 April 1977" 
date2 = "7 July 2017" 

date1 = dmy(date1) 
date2 = dmy(date2) 
number_of_months = (year(date1) - year(date2)) * 12 + month(date1) - month(date2) 

差異個月= 12 *在年+差差在幾個月內。

下面可能需要使用ifelse條件 月減法

相關問題