web-dev-qa-db-ja.com

2つの日付間の月数

Rの2つの日付間の月数を計算する標準/一般的な方法/式はありますか?

MathWorks months関数 に似たものを探しています

61
knguyen

これは簡単だと言いましたが、difftime()は数週間で止まります。なんて奇妙だ。

可能な答えの1つは、何かをハックすることです。

# 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の振る舞いと一致する分数差を表現する信頼できる方法がないため、除外します。

55

シンプルな機能...

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

私にとって、この問題を単に2つの日付を減算することとして考えるのは理にかなっています。 minuend − subtrahend = difference(wikipedia) なので、後の日付をパラメーターリストの最初に置きます。

負の数を減算するための規則のおかげで、それらの日付が負の年の内部表現を持っているにもかかわらず、1900年より前の日付では正常に動作することに注意してください...

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

もっと簡単な方法があるかもしれません。関数ではありませんが、1行だけです。

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

これは、2つの日付間の月全体の数を計算します。月全体ではない現在の月/残りを含める場合は、-1を削除します。

34
Dominic

これは、MathWorks関数と同等の観点から尋ねられた質問に対するより近い答えだと思います

MathWorksの月数関数

MyMonths = months(StartDate, EndDate, EndMonthFlag)

私のRコード

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

出力(コードが2016年4月に実行されたとき)

[1] 6

Lubridate [パッケージ]は、日付の解析と操作を簡単にするツールを提供します。これらのツールは、共通の目的ごとにグループ化されています。各関数の詳細については、ヘルプドキュメントをご覧ください。

interval {lubridate}は、指定された開始日と終了日でInterval-classオブジェクトを作成します。開始日が終了日より前に発生する場合、間隔は正になります。それ以外の場合、負になります

今日{lubridate}現在の日付

months{Base}月の抽出これらは一般的な関数です。内部日時クラスのメソッドはここに文書化されています。

%/%{base}は整数除算AKA(x%/%y)を示します(丸め誤差まで)

33
mtelesha

R-Helpメーリングリストには、あなたと同じようなメッセージがあります(以前にCRANリストについて言及しました)。

ここ リンク 。推奨される解決策は2つあります。

  • 月あたり平均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
14
Manoel Galdino
library(lubridate)

case1:ナイーブ関数

mos<-function (begin, end) {
      mos1<-as.period(interval(ymd(begin),ymd(end)))
      mos<-mos1@year*12+mos1@month
      mos
}

case2:「日」に関係なく「月」のみを考慮する必要がある場合

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<-mob1@year*12+mob1@month
      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
5
hyunwoo jeong
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条件を使用して修正する必要がある場合があります

4
Ajay Ohri

私にとってこれはうまくいったものです:

library(lubridate)

Pagos$Datediff <- (interval((Pagos$Inicio_FechaAlta), (Pagos$Inicio_CobFecha)) %/% months(1))

出力は、2つの日付間の月数であり、Pagosデータフレームの列に格納されます。

2
EDUARDO ROLDAN

別の短くて便利な方法は次のとおりです。

day1 <- as.Date('1991/04/12')
day2 <- as.Date('2019/06/10')
round(as.numeric(day2 - day1)/30.42)

[1] 338

0
JAQuent

月の日付差

$date1 = '2017-01-20';
$date2 = '2019-01-20';

$ts1 = strtotime($date1);
$ts2 = strtotime($date2);

$year1 = date('Y', $ts1);
$year2 = date('Y', $ts2);

$month1 = date('m', $ts1);
$month2 = date('m', $ts2);

echo $joining_months = (($year2 - $year1) * 12) + ($month2 - $month1);
0
Kamlesh