1
%let months_back = %sysget(months_back);

data;
        m = intnx('month', "&sysdate9"d, -&months_back - 2, 'begin');
        m = intnx('day', put(m, date9.), 26, 'same');
        m2back = put(m, yymmddd10.);
        put m2back;
run;

注: 文字値は、(行):(列) で指定された場所で数値に変換されています。5:19 注: 無効な数値データ '01OCT2012' が 5 行目の 19 列目にあります。

なぜこれがうまくいかないのか、私には本当にわかりません。日付文字列が数値データ?

4

2 に答える 2

4

ここでは PUT(m, date9.) が犯人です。INTNX の 2 番目の引数は数値 (つまり日付) である必要があります。PUT 関数は常に文字値を返します。この例では '01OCT2012' です。PUT 関数を完全に削除するだけで、コードが機能するはずです。

m = intnx('day', m, 26, 'same');
于 2012-12-04T13:09:42.547 に答える
1

SASは日付を数値として格納しますが、実際には、日付を完全に区別するタイプはありません。SASの日付は、1960年1月1日からの日数であるため、今日では19000を少し超えています。日付形式は、日付の計算とはまったく関係ありません。人間が読みやすいようにするためだけのものです。

あなたが言うビット:

"&sysdate9"d

実際には、文字列「01JAN2012」を数値(18304)に変換します。

あなたがやろうとしていることを達成するためのより速い方法が実際にあります。日数はSASの整数に対応しているため、1日インクリメントするには、値に1を追加するだけです。

例えば:

%let months_back=5;
data _null_;
        m = intnx('month', today(), -&months_back - 2, 'begin');
        m2 = intnx('day', m, 26, 'same');
        m3 = intnx('month',"&sysdate9"d, -&months_back - 2)+26;
        m2back = put(m2, yymmdd10.);
        put m= date9. m2= yymmdd10. m3= yymmdd10.;
run;

M3は、MONTH間隔を使用し、次に26を加算することにより、計算全体を1つのステップで実行します。INTNX('day' ...)は、関数の使用に他の値がない限り(たとえば、シフトインデックスを使用)、基本的に無意味です。

ここでPUT(log)ステートメントでフォーマットの使用を確認することもできます-フォーマットされた値を取得するために、それを文字値にPUTしてからログに入れる必要はなく、(var)(format 。); -そして、そのように好きなだけつなぎ合わせます。

また、「&sysdate9。」dは現在の日付を取得するための最良の方法ではありません。&sysdate。はSASの起動時にのみ定義されるため、セッションが3日間実行された場合、当日にはなりません(おそらくそれが望ましいのでしょうか?)。代わりに、TODAY()関数は、SASセッションが実行されている期間に関係なく、現在の日付を最新の状態で取得します。

最後にdata _null_;、データセットが必要ない場合はお勧めします(必要な場合は、結果データセットに名前を付けます)。 data _null_データセットを作成しません。データ; データセット(data1、data2、...)の数を増やすだけで、ワークスペースがすぐにいっぱいになり、何をしているのかわかりにくくなります。

于 2012-12-04T16:07:43.073 に答える