1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SASでデータ加工時の備忘録

Last updated at Posted at 2024-03-10

機械学習用のデータセットをSASで作成していて、いろいろな加工を試したのでそのメモです。

日付操作

日付を表す数値8桁のカラムから日にちを取得する

例: 20240310 → 10 を取得

proc sql;
    select
        date, /* 数値8桁のカラム */
        mod(date, 100) as day /* 末尾の2桁を取り出す */
    from
        table
    ;
quit;

日付型のカラムから日にちを取得する

例: 2024-03-10 → 10 を取得

proc sql;
    select
        date, /* 日付型のカラム */
        day(date) as day /* 日にちの2桁を取り出す */
    from
        table
    ;
quit;

数値型の日付(YYYYMMDD形式)のカラムから指定した年月との月数の差分を計算

例: 202312 - 20230301 → 9

%let target_ym = 202312;  /* YYYYMM形式 */

proc sql;
    select 
        date,  /* 数値8桁のカラム */
        intck('month', 
              input(put(date, 8.), yymmdd8.), 
              input(put(&target_ym, 6.) || '01', yymmddn8.)) as month_diff
    from
        table
    ;
quit;

数値型の日付(YYYYMMDD形式)のカラムから指定した年月での年齢を計算

例: 202312 - 19920806 → 31

%let target_ym = 202312;  /* YYYYMM形式 */

proc sql;
    select 
        birthday,
        int(yrdif(input(put(birthday, 8.), yymmdd8.), input(put(target_ym.01, 8.), yymmdd8.)), 'AGE') as age
    from
        table
    ;
quit;

日付変数の作成

※グローバル変数として定義するため以降のプロセスで利用可能

未来月

例: 2312 → yymm1after = 2401 ~ yymm12after = 2412

%macro create_future_dates(yymm);

    %let year = %substr(&yymm, 1, 2);
    %let month = %substr(&yymm, 3, 2);
    %let base_date = %sysfunc(mdy(&month, 1, 20&year));

    %do i = 1 %to 12;
        %let future_date = %sysfunc(intnx(month, &base_date, &i, e));
        %let future_yymm = %sysfunc(putn(&future_date, yymmn6.));
        %global yymm_&i.after;
        %let yymm_&i.after = %substr(&future_yymm, 3, 4);
		%put yymm_&i.after = %substr(&future_yymm, 3, 4);
    %end;

%mend create_future_dates;

/* 実行 */
%create_future_dates(2312);

過去月

例: 2312 → yymm1before = 2311 ~ yymm12before = 2212

%macro create_past_dates(yymm);

    %let year = %substr(&yymm, 1, 2);
    %let month = %substr(&yymm, 3, 2);
    %let base_date = %sysfunc(mdy(&month, 1, 20&year));

    %do i = 1 %to 12;
        %let past_date = %sysfunc(intnx(month, &base_date, -&i, e));
        %let past_yymm = %sysfunc(putn(&past_date, yymmn6.));
        %global yymm_&i.before;
        %let yymm_&i.before = %substr(&past_yymm, 3, 4);
		%put yymm_&i.before = %substr(&past_yymm, 3, 4);
    %end;

%mend create_past_dates;

/* 実行 */
%create_past_dates(2312);

文字列操作

数値型のカラムを取得し、頭に文字列をつけて連結し、文字列型として取得

例: 3 → num_3

proc sql;
    select
        catx('_', 'num', category) as category_str
    from
        table
    ;
quit;

文字列の数字を削除

例: 電話料金10月分 → 電話料金月分

data modified_data;
    set original_data;
    modified_column = kcompress(column_name, '01234567890123456789'); /* 前半の数字は半角、後半の数字は全角 */
run;

数値操作

傾きの作成(例として3変数)

m = \frac{N \sum (xy) - \sum x \sum y}{N \sum (x^2) - (\sum x)^2}

例: [100, 110, 120] → 10 / [15, 10, 5] → -5

proc sql;
    select
        user_id,
        income1,
        income2,
        income3,
        (3 * (sum(1*income1 + 2*income2, 3*income3)) - (sum(1+2+3) * sum(income1 + income2 + income3))) / (3 * sum(1*1 + 2*2 + 3*3) - (sum(1+2+3))**2) as income_slope
    from
        table
    group by
        user_id
    ;
quit;

その他

インデックス用のカラムを作成し連番を付与

data index_dataset;
    set no_index_dataset;
    index = _N_ ; /* 上から順番に1,2,3,,を付与する */
run;

作成したデータセットをCSVエクスポート

libname mylib 'C:\your\library\path';

proc export data=your_dataset
    outfile='&mylib.\output.csv'
    dbms=csv
    replace;
run;

2つのデータセットが同一かを調べる(リファクタリング時など)

proc compare base=dataset_before compare=dataset_after;
run;
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?