データの日付を読む
このモジュールでは、SASで日付変数を読み、日付関数を使用し、日付表示形式を使用する方法を紹介します。 SASにデータを読み込むためのデータステップや、新しい変数を計算するための代入文には慣れていることが前提です。 もし、全く新しいコンセプトがある場合は、下記のFor more informationに他の学習モジュールへの案内がありますので、そちらをご覧ください。 最初の例で使用するデータファイルは、次に示すとおりです。
John 1 Jan 1960Mary 11 Jul 1955Kate 12 Nov 1962Mark 8 Jun 1959
以下のプログラムはデータを読み込み、datesという一時データファイルを作成する。 なお、日付の読み込みはデータステップで行い、書式はdate11.を使用している。
DATA dates; INPUT name $ 1-4 @6 bday date11.;CARDS;John 1 Jan 1960Mary 11 Jul 1955Kate 12 Nov 1962Mark 8 Jun 1959;RUN;PROC PRINT DATA=dates;RUN;
プロックプリントの出力は以下の通りです。 データ中の日付とbdayの値を比較する。 Johnの日付は1960年1月1日で、bdayの値は0であることに注意してください。これは、SASでは日付が1960年1月1日からの日数として内部に格納されているためです。 Maryは1960年より前に生まれたので、彼女のbdayの値は負(-1635)である。
OBS NAME BDAY 1 John 0 2 Mary -1635 3 Kate 1046 4 Mark -207
私たちが理解できる方法で日付を見るには、出力をフォーマットする必要があります。 ddmmmyyyyの形式で日付を見るには、date9.フォーマットを使用します。 これは、formatステートメントで指定します。
PROC PRINT DATA=dates; FORMAT bday date9. ;RUN;
以下は、上記のproc printステートメントによって生成された出力です。
OBS NAME BDAY 1 John 01JAN1960 2 Mary 11JUL1955 3 Kate 12NOV1962 4 Mark 08JUN1959
次のデータを見てみましょう。 一見すると、日付が違いすぎて読めないように見えます。
1) 月が数字であること、
2) 月、日、年の順で並んでいること、が共通点です。John 1 1 1960Mary 07/11/1955Joan 07-11-1955Kate 11.12.1962Mark 06081959
これらの日付は、同じフォーマットであるmmddyy11で読むことができます。 そのフォーマットをデータステップで使用する例を以下に示す。
DATA dates; INPUT name $ 1-4 @6 bday mmddyy11.;CARDS;John 1 1 1960Mary 07/11/1955Joan 07-11-1955Kate 11.12.1962Mark 06081959;RUN;PROC PRINT DATA=dates; FORMAT bday date9. ;RUN;
上記のproc printの結果、すべての日付が正しく読み取られていることがわかります。
OBS NAME BDAY 1 John 01JAN1960 2 Mary 11JUL1955 3 Joan 11JUL1955 4 Kate 12NOV1962 5 Mark 08JUN1959
SASに日付を読み込む際に利用できるフォーマットは多岐にわたります。 以下は、それらのフォーマットのいくつかのサンプルです。
Informat Description Range Width Sample-------- ----------- ----- ------- ------JULIANw. Julian date 5-32 5 65001 YYDDDDDMMYYw. date values 6-32 6 14/8/1963MONYYw. month and year 5-32 5 JUN64YYMMDDw. date values 6-32 8 65/4/29YYQw. year and quarter 4-32 4 65Q1
月、年、日の順で並んでいる次のデータを考えてみましょう。
7 1948 11 1 1960 110 1970 1512 1971 10
これらのデータは、この後のデータステップのように、日付の各部分を別の変数にして読み込んでもよいでしょう。
DATA dates; INPUT month 1-2 year 4-7 day 9-10; bday=MDY(month,day,year);CARDS; 7 1948 11 1 1960 110 1970 1512 1971 10;RUN;PROC PRINT DATA=dates; FORMAT bday date9. ;RUN;
データステップの中の関数mdy(month,day,year)に注目しましょう。 この関数は、個々の構成要素から日付値を作成するために使用されます。 proc printの結果は以下の通りです。
OBS MONTH YEAR DAY BDAY 1 7 1948 11 11JUL1948 2 1 1960 1 01JAN1960 3 10 1970 15 15OCT1970 4 12 1971 10 10DEC1971
2桁の日付
次のデータを考えてみましょう。これは、年を表すのに2桁だけが使われ、年が最後に表示される以外は上記と同じものです。
7 11 18 7 11 48 1 1 6010 15 7012 10 71
データの読み方は先程と同じです。
DATA dates; INPUT month day year ; bday=MDY(month,day,year);CARDS; 7 11 18 7 11 48 1 1 6010 15 7012 10 71;RUN;PROC PRINT DATA=dates; FORMAT bday date9. ;RUN;
procのprintの結果は以下のようになります。
OBS MONTH DAY YEAR BDAY 1 7 11 18 11JUL1918 2 7 11 48 11JUL1948 3 1 1 60 01JAN1960 4 10 15 70 15OCT1970 5 12 10 71 10DEC1971
ここで2桁の年が機能するのは、SASが2桁の年を2000年以上と解釈し、それ以降は1999年以下と解釈するカットオフ(yearcutoff)を仮定しているためです。 デフォルトのyearcutoffはSASのバージョンによって異なります:
SAS 6.12 and before (YEARCUTOFF=1900)SAS 7 and 8 (YEARCUTOFF=1920)
この後のプログラムのオプション文はyearcutoffの値を1920に変更しています。 これにより、20より小さい2桁の年は、2000年以降と読み替えられます。 このオプションを設定した場合、次に同じプログラムを実行すると、異なる結果が得られます。
OPTIONS YEARCUTOFF=1920;DATA dates; INPUT month day year ; bday=MDY(month,day,year);CARDS; 7 11 18 7 11 48 1 1 6010 15 7012 10 71;RUN;PROC PRINT DATA=dates; FORMAT bday date9. ;RUN;
proc printの結果は以下の通りです。 最初の観測は1918年ではなく、2018年に発生したと読み取れるようになりました。
OBS MONTH DAY YEAR BDAY 1 7 11 18 11JUL2018 2 7 11 48 11JUL1948 3 1 1 60 01JAN1960 4 10 15 70 15OCT1970 5 12 10 71 10DEC1971
経過した日付を使った計算
SASの日付変数は日付を含む計算を非常に便利にしてくれます。 例えば、2000年1月1日の全員の年齢を計算する場合、データステップで以下のように変換します。
age2000=(mdy(1,1,2000)-bday)/365.25 ;
この計算をコンテキストにしたプログラムは以下の通りです。
OPTIONS YEARCUTOFF=1900; /* sets the cutoff back to the default */DATA dates; INPUT name $ 1-4 @6 bday mmddyy11.; age2000 = (MDY(1,1,2000)-bday)/365.25 ;CARDS;John 1 1 1960Mary 07/11/1955Joan 07-11-1955Kate 11.12.1962Mark 06081959;RUN;PROC PRINT DATA=dates; FORMAT bday date9. ;RUN;
このproc printの結果は以下の通りです。 変数AGE2000には、2000年1月1日時点の年齢(歳)が格納されるようになった。
OBS NAME BDAY AGE2000 1 John 01JAN1960 40.0000 2 Mary 11JUL1955 44.4764 3 Joan 11JUL1955 44.4764 4 Kate 12NOV1962 37.1362 5 Mark 08JUN1959 40.5667
その他の便利な日付関数
日付変数を使用するための便利な関数がたくさんあります。 以下にそれらの関数のいくつかを列挙します。
Function Description Sample-------- --------------------- -----------------month() Extracts Month m=MONTH(bday);day() Extracts Day d=DAY(bday) ;year() Extracts Year y=YEAR(bday);weekday() Extracts Day of Week wk_d=WEEKDAY(bday);qtr() Extracts Quarter q=QTR(bday);
以下のプログラムは、これらの関数の使い方を示しています。
DATA dates; INPUT name $ 1-4 @6 bday mmddyy11.; m=MONTH(bday); d=DAY(bday) ; y=YEAR(bday); wk_d=WEEKDAY(bday); q=QTR(bday);CARDS;John 1 1 1960Mary 07/11/1955Joan 07-11-1955Kate 11.12.1962Mark 06081959;RUN;PROC PRINT DATA=dates; VAR bday m d y; FORMAT bday date9. ;RUN;PROC PRINT DATA=dates; VAR bday wk_d q; FORMAT bday date9. ;RUN;
プロックの印刷結果は以下のとおりです。 新しい変数には、月、日、年、曜日、四半期が含まれています。
OBS BDAY M D Y 1 01JAN1960 1 1 1960 2 11JUL1955 7 11 1955 3 11JUL1955 7 11 1955 4 12NOV1962 11 12 1962 5 08JUN1959 6 8 1959OBS BDAY WK_D Q 1 01JAN1960 6 1 2 11JUL1955 2 3 3 11JUL1955 2 3 4 12NOV1962 2 4 5 08JUN1959 2 2
概要
- 日付は日付フォーマット、最も一般的にはdate9.とmmddyy11で読み取ります。
- 日付関数は、その構成要素から日付値を作成したり (mdy(m,d,y)) 、日付値から構成要素を抽出する (month(),day() など) ために使用することができます。
- 2桁の年を読まなければならない場合、yearcutoffオプションが使用されることがあります。
注意すべき問題点
- フィールド内で日付が混在しており、どの日付フォーマットでも読み込むことができない。 解決策 フィールドを文字フィールドとして読み取り、文字列をテストし、入力関数と適切なフォーマットを使用して値を日付変数に読み込んでください。
- 日付を読み取ることができる書式がありません。 解決策:日付をコンポーネントとして読み取り、関数を使用して日付値を生成します。
- yearcutoff のデフォルトが、上記のパッケージのバージョンのデフォルトでないことがあります。 解決策: yearcutoff の現在の設定を決定するために、
PROC OPTIONS OPTION=YEARCUTOFF; RUN;
これを含むプログラムを単に実行すると、yearcutoff の現在の値を含む出力が表示されます。