# SAS

# DS2

# if-then/elseステートメント

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/p1swn0a4ufdvn3n1e67d75roy6ns.htm>

# do untilステートメント

条件が真になるまで、処理をループする。
<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/p0p2sapr15j0z4n14o4b0v1i2xb7.htm#n0y0tj44j79ow1n15beup6finonl>

```
proc ds2;
  data _null_;
    method run();
      k = 1;
      do until(k > 6);
         k = k + 1;
      end;
    end; /* method end*/
  enddata;
end;
```

# methodステートメント

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/p0vkktkd156jhqn11izdgfpg0hou.htm>

# dataステートメント

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n1ew9uzutoyamjn1kzz8f194xhes.htm>

# selectステートメント

CASE文を記述する。
<https://go.documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n01kskkbawu6isn1vee8uw50jzvu.htm>

- 基本の書き方
  - `select(variable); when(1) 処理1; when(2) 処理2; end;`
- 個別の処理行が1行に収まらないときは、do; 〜 end;で括る。
  - `select(variable); when(1); do; 処理1; end; when(2); do; 処理2; end; end;`
- どれにも該当しないときの処理行は、whenの代わりにotherwiseで記述する。

**▼基本の書き方**
``` sas
  select(variable);
    when(1) 処理1;
    when(2) 処理2;
  end;`
```

**▼個別の処理行が1行に収まらないとき**
``` sas
  select(variable);
    when(1); do;
      処理1-1;
      処理1-2;
      処理1-3;
    end;
    when(2) 処理2;
  end;`
```


**▼より細かい条件式で分岐したいとき**

``` sas
  mon = 'JUN';
  temp = 30
  select;
    when (mon in ('JUN', 'JUL', 'AUG') and temp > 28);
      put 'SUMMER ' mon=;
    when (mon in ('MAR', 'APR', 'MAY'));
      put 'SPRING ' mon=;
    otherwise;
      put 'FALL OR WINTER ' mon=;
  end;
```

# jsonパッケージ > getNextTokenメソッド

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n1qnsau40tm51pn169k767jyw7is.htm>

# httpパッケージ > executeMethodメソッド

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n1we0n5bkmxyj3n1oglx8is6ogqo.htm>

# httpパッケージ > setResponseBodyCharacterSetメソッド

UTF-8を指定したいときは、 `http_pkg.setResponseBodyCharacterSet('UTF-8')`とする。

[https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n057ts3z5uqaemn1vtd7vayor79q.htm](https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n057ts3z5uqaemn1vtd7vayor79q.htm)

# httpパッケージ > addSASOAuthTokenメソッド

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/p0wc0obw28cy6wn1q8kvblfjf6vc.htm>

# YYMMDDxw. 出力形式

`yyyy-mm-dd`や`yyyy/mm/dd`といった形式でSAS日付値を出力する。
<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n02pxkowzaiavfn1lwe6v95ps5pg.htm>

# BESTw. 出力形式

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/p06s6plgjq7rugn1fdf0sckkz0hx.htm>

# 式の演算子

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2pg/p0vinswrxk1819n1qizkibfin0cy.htm>

### 算術演算子

|演算子|機能|
|-|-|
|+|加算|
|-|減算|
|*|乗算|
|/|除算|
|**|累乗|
|><|左辺右辺の最小値を取得|
|<>|左辺右辺の最大値を取得|

### 関係演算子
関係を満たすとき(True)は1、そうでないとき(False)は0を返す。  
（データグリッド関数等で指定する際は、単一引用符`'`で括る）

|演算子|機能|
|-|-|
|=, eq|等しい(Equal)|
|^=, ~=, ne|等しくない(Not Equal)|
|>, gt|より大きい(Greater Than)|
|>=, ge|以上(Greater Equal)|
|<, lt|より小さい(Lesser Than)|
|<=, le|以下(Lesser Equal)|

### 論理演算子

|演算子|機能|備考|
|-|-|-|
|not, ^, ~|論理否定|`not ～`のように前置する。|
|or, \|, !|論理和|
|and, &|論理積|

### IN演算子
リスト内に存在しているかどうかを判定する

|式|入力値|判定値|
|-|-|-|
|`a in (1, 2, 3)`|a = 1| 1(True)|
|`a not in (1, 2, 3)`|a = 1| 0(False)|

### その他の演算子


|内容|演算子|
|-|-|
|文字列を結合する|\|\|, !!|

# DS2言語の予約語

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2pg/p1rnsddd78roken1tlwnfk4poavl.htm>

# leaveステートメント

ループ処理を中断し、ループの外の処理を継続する。

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/p1irdset32xggmn1c7dwqmthxvnd.htm>

# データグリッド関数

# jsonテキストからデータグリッドを生成する

<details><summary>DATAGRID_CREATE関数</summary>

``` sas
DATAGRID_CREATE(dataGrid, jsonString);

/* 使用例 */
dcl package datagrid dg();
jsonString = '[{"metadata":[{"column_1":"string"}]},{"data":[["text1"], ["text2"]]}]';
DATAGRID_CREATE(dg, jsonString);
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/p1b00g0lvqulmxn196x7y6q92yxb.htm>

</details>

# データグリッドを複製する

<details><summary>DATAGRID_COPY関数</summary>

``` sas
DATAGRID_COPY(sourceDataGrid, targetDataGrid)
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/p0ff2os5c08sj7n1oel2xofoqyny.htm>

</details>

# 列定義を保持したまま、行だけを削除する

<details><summary>DATAGRID_CLEARDATA関数</summary>

``` sas
DATAGRID_CLEARDATA(dataGrid)
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/n1shy8y4bvhh6gn112k7w50mpifx.htm>

</details>

# 列を追加する

<details><summary>DATAGRID_ADDCOLUMN関数</summary>

``` sas
DATAGRID_ADDCOLUMN(dataGrid, columnName, columnType);
```

- columnTypeに想定外の値が入っている場合、列の追加は行われない。
- 使える型名は以下。
  - boolean, bool, double, decimal, integer, int, long, string

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/n1djgke34f9wdhn15rsisdozptej.htm>
</details>

# 列を削除する

<details><summary>DATAGRID_DELETECOLUMN関数</summary>

``` sas
DATAGRID_DELETECOLUMN(dataGrid, columnName);
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/n07yra1v2tnuxdn1ei3rsz8lzi2h.htm>

</details>

# 行を追加する

<details><summary>DATAGRID_ADDROW関数</summary>

``` sas
DATAGRID_ADDROW(データグリッド変数, <任意>追加する行数)
```

下記のように記述すると「追加した行は今何行目にあるか」を取得することができる。  
（関数の返り値として整数が返ってくる為）

``` sas
datagrid_rownum = DATAGRID_ADDROW(dataGrid);
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/n109izonc0diazn0z2gy6wqehync.htm>

</details>

# 行を削除する

<details><summary>DATAGRID_DELETEROW ... 行を削除する</summary>

``` sas
DATAGRID_DELETEROW(dataGrid, deleteRowNumber);
```

行番号を指定し、データグリッドの行を削除する。  

``` sas
DATAGRID_DELETEROW(dataGrid, 5);
```

複数行削除する場合は下記のように記述する。（この場合、5～8行目が削除される）

``` sas
DATAGRID_DELETEROW(dataGrid, 5, 8);
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/n0cx6kthm2pdkgn1l2zlad29nlel.htm>

</details>

# データグリッド内の値を取得する

<details><summary>DATAGRID_GET関数</summary>

``` sas
value = DATAGRID_GET(dataGrid, columnName, rowNumber)
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/n04ham6nlknk8ln17nuk76nue4vw.htm>

</details>

# 値を代入する

<details><summary>DATAGRID_SET関数</summary>

``` sas
DATAGRID_SET(dataGrid, columnName, rowNumber, settingValue)
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/p0danjcrv2wxttn1isg5kq69rcb2.htm>

</details>

# 条件に一致する行のうち、1番目の行から値を取得する

<details><summary>DATAGRID_FILTEREDGET ... 条件に一致する行のうち、1番目の行から値を取得する</summary>

条件に一致する行のうち、1番目の行から値を取得する。
（条件を満たす行が複数存在する場合は、最初に条件と一致した行から値を取得する）

``` sas
DATAGRID_FILTEREDGET(dataGrid, columnName, filterColumnName, operator, filterValue)

/* 使用例 */
status = DATAGRID_FILTEREDGET(DebtEval, 'approvalStatus', 'riskGroup', 'EQ', 'Low')
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/n1mwcqt8wn70gxn17vwqtle2lgod.htm>

</details>

# 条件に一致する行のうち、1番目の行番号を取得する

<details><summary>DATAGRID_FILTEREDGETINDEX ... 条件に一致する行のうち、1番目の行番号を取得する</summary>

条件に一致する行のうち、1番目の行番号を取得する。  
（条件を満たす行が複数存在する場合は、最初に条件と一致した行の番号を取得する）

``` sas
DATAGRID_FILTEREDGETUINDEX(dataGrid, columnName, filterColumnName, operator, filterValue)

/* 使用例 */
row_num = DATAGRID_FILTEREDGETINDEX(DebtEval, 'approvalStatus', 'riskGroup', 'EQ', 'Low')
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/n15xvdgven63q0n1rnu3uktmf9cq.htm>

</details>

# 行数を取得する

<details><summary>DATAGRID_COUNT関数</summary>

``` sas
row_count = DATAGRID_COUNT関数(dataGrid);
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/p0wg7r5h8ayh0bn173vtjch62vql.htm>

</details>

# 指定列の合計値を取得する

<details><summary>DATAGRID_SUM ... 指定列の合計値を取得する</summary>

``` sas
DATAGRID_SUM(dataGrid, column)

/* 使用例 */
payment_sum = DATAGRID_SUM(dataGrid, 'payment');
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/p1du23931dz4tgn1vdf3ahx05qbe.htm>

</details>

# 列名と条件を指定し、条件に一致する行数を取得する

<details><summary>DATAGRID_MATCHCOUNT関数</summary>

``` sas
row_count = DATAGRID_MATCHCOUNT(dataGrid, column_name, operator, match_value);

/* 記述例 */
row_count = DATAGRID_MATCHCOUNT(dataGrid, 'is_complete_flg', '=', 'Y');
```

使える演算子は以下。

|Operator|Description|
|-|-|
|EQ, =, ==|一致する|
|NE, !=, ^=, <>|一致しない|
|GT, >|よりも大きい|
|LT, <|よりも小さい|
|LE, <=|以下|
|GE, >=|以上|

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/n1ic8wboejbzb6n11vltlxtnz2is.htm>

</details>

# データグリッドをソートする

<details><summary>DATAGRID_SORT関数 ... データグリッドをソートする</summary>

``` sas
DATAGRID_SORT(sourceDataGrid, sortColumn, sortOrder, targetDataGrid)
```

sortOrderには`'A'`(昇順)または`'D'`(降順)を指定する。

``` sas
DATAGRID_ADDROW(dataGrid, 'column1', 'A', dataGridSorted);
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/n08c59acvwpzx3n1pf4z22crgobo.htm>

</details>

# jsonテキストとして内容を取得する

<details><summary>DATAGRID_TOSTRING関数</summary>

``` sas
str = DATAGRID_TOSTRING(dataGrid);
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/n1d2o8h7l2hbxfn17wrmnkg2zulw.htm>

</details>

# 内容をログに出力する

<details><summary>DATAGRID_DUMPTOLOG関数</summary>

``` sas
DATAGRID_DUMPTOLOG(データグリッド変数)
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/p1da42svmyhzygn1r1f2uq10ntsh.htm>

</details>

# 2つのデータグリッドとそのカラム名を指定し、値が一致している行数を算出する

<details><summary>DATAGRID_GRIDMATCHCOUNT関数</summary>

``` sas
row_count = DATAGRID_GRIDMATCHCOUNT(dataGrid1, dataGrid2, column1, column2);
row_count = DATAGRID_GRIDMATCHCOUNT(dataGrid1, dataGrid2, keyColumn);
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/n1j3q1ssilim7qn16y4q1wwkje0x.htm>

</details>

# 2つのデータグリッドを縦方向に結合する

<details><summary>DATAGRID_APPEND ... 2つのデータグリッドを縦方向に結合する</summary>

``` sas
DATAGRID_APPEND(dataGrid1, dataGrid2)
```

dataGrid2の行を、dataGrid1に追加する。  
返り値として、縦結合後のデータグリッドの行数を返す。

``` sas
rownum = DATAGRID_APPEND(dataGrid1, dataGrid2)
```

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmdatagrids/n0plj4pbqiaxwnn1gzcgik62kxf7.htm>

</details>

# DS2関数(文字列)

# 文字列の長さを取得する

<details><summary>LENGTH関数</summary>

``` sas
val = length(str);
```

...

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n1lbye3jnh3aipn16jqqkbv4gnsg.htm>

</details>

# 文字列中の指定文字列の位置を取得する

<details><summary>FIND関数</summary>

``` sas
pos = find(string, substring);
pos = find(string, substring, startpos);
```

...

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n1v0tzf4xq363mn15mnppqtk2zti.htm>

</details>

# 入力された文字列を区切り、n番目の単語を取得する

<details><summary>SCAN関数</summary>

`str = scan(input_str, n, delimiter);`

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/p13adatt2vvhcxn1ext6w6eet24p.htm>

</details>

# DS2関数(文字列の加工)

# 文字列を切り出す

<details><summary>SUBSTR関数</summary>

``` sas
trimmed_str = substr(str, start_pos, length);
```

...

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/p0mce96o6y74fzn1ro3vtputzhut.htm>

</details>

# 文字列を結合する

<details><summary>CAT関数（先頭・末尾の空白を削除しない）</summary>

先頭または末尾の空白を削除せずに、連結文字列を返す。

``` sas
text = cat('aaa', 'bbb', 'ccc');
```

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n0somj6dsx2dmkn1vqjabhvt6nv4.htm>
</details>


<details><summary>CATS関数（先頭・末尾の空白を削除する）</summary>

先頭と末尾の空白を削除して、連結文字列を返す。

``` sas
text = cats('aaa', 'bbb', 'ccc');
```

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n0h2zi3y876365n1bjrpv8seizpf.htm>
</details>


<details><summary>CATX関数（区切り文字を挿入する）</summary>

先頭と末尾の空白を削除したうえで区切り文字を挿入し、連結文字列を返す。

``` sas
text = catx(',', 'aaa', 'bbb', 'ccc');
```

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n0dj69cad78xvgn19rbwpiyx9vmg.htm>
</details>

# 部分文字列を置換する

<details><summary>TRANWRD関数</summary>

``` sas
str = tranwrd(inputstr, beforesubstr, after_substr);
```

...

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/p01iwnq51ps93bn1t9d1eztkx8go.htm>

</details>

# すべての文字を小文字にする

<details><summary>LOWCASE関数</summary>

``` sas
str = lowcase('INTRODUCTION');
```

...

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n0mwurvelifv54n18gbah5nmefn5.htm>

</details>

# 文字列をURLエンコードする

<details><summary>URLENCODE関数</summary>

``` sas
text = urlencode(input_text);
```

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n10igvbv55geofn1esixotiud7t9.htm>

</details>

# DS2関数(日付と時間)

# 「月, 日, 年」をそれぞれ引数で受け取り、SAS日付値に変換する

<details><summary>MDY関数</summary>

``` sas
date_val = mdy(mm, dd, yy);
```

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n15zqld58pd186n1djkzia6oprza.htm>

</details>

# SAS日時値からSAS日付値を取得する

<details><summary>DATEPART関数</summary>

``` sas
sas_date = DATEPART(sas_datetime);
```

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n16yabgpgl3slnn1uh9ipw6qlrdo.htm>

</details>

# 現在の日時を取得する

<details><summary>DATETIME関数</summary>

``` sas
sas_datetime = DATETIME();
```

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/p037ecmn1cv535n1op7wm4qnza7a.htm>

</details>

# SAS日時値から、日付や時間を加減算する

<details><summary>INTNX関数</summary>

``` sas
INTNX(interval, target_value, increment)
```

``` sas
/* 使用例 */
dcl double date_after6week having format yymmdds10.;
input_date = inputn('20250831', 'yymmdd8.');
date_after6week = intnx('week', input_date, 6); /* 6週間後の日付を取得する */
put date_after6week=; /* "2025/10/12"が出力される */
```

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n1mtvizfg1y0g9n1wslqgjxseh0i.htm>

</details>

# 2つのSAS日時値の間隔を取得する

<details><summary>INTCK関数</summary>

``` sas
INTCK(interval, startDate, endDate, <任意>method)
```

``` sas
proc ds2;
  data _null_;
    method run();
      dcl double startDate endDate mon day;
   
      startDate = inputn('2023/12/11', 'yymmdd10.');
      endDate = inputn('2025/12/01', 'yymmdd10.');

      mon = INTCK('MONTH', startDate, endDate, 'CONTINUOUS');      
      put mon=;

      day = INTCK('DAY', startDate, endDate, 'CONTINUOUS');      
      put day=;
    end;
  enddata;
run;
quit;

```


**interval**

|計算単位|指定する文字列|
|-|-|
|日|DAY|
|週|WEEK|
|月|MONTH|
|四半期|QTR|
|年|YEAR|
|秒|SECOND|
|分|MINUTE|
|時|HOUR|

**method**

|指定する文字列|内容|
|-|-|
|CONTINUOUS, C, CONT|連続した期間を測定単位に指定します。|
|DISCRETE, D, DISC|連続しない期間を測定の単位に指定します。DISCRETEメソッドは、間隔の境界(月末など)を数えます。|

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/ds2ref/n096g3nwx05g7wn161ax2rdqmlfn.htm>

</details>

# CAS

# DS2コードでCASにテーブルを読み込む

<details><summary>table.loadTableアクション</summary>

``` sas
proc cas;
  session casauto;
  table.loadTable / 
    sourceCaslib = "mylib" /* 左辺は caslib でも可 */
  , path = "inputdata.sas7bdat"
  , casout = {
      caslib = "public"
    , name = "target_table_name"
    , replace = true
    };
  run;
quit;
```

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/caspg/cas-table-loadtable.htm>

</details>

# CASテーブルをセッションスコープからグローバルスコープへ昇格する

<details><summary>table.promoteアクション</summary>

``` sas
proc cas;
  session casauto;
  table.promote / 
    sourceCaslib = "mylib" /* 左辺は caslib でも可 */
  , name = "table_name"
  , targetCaslib = "public"
  , target = "target_table_name"
  , quiet = false
  ;
  run;
quit;
```

<https://documentation.sas.com/doc/ja/pgmsascdc/v_061/caspg/cas-table-promote.htm>

</details>

# Intelligent Decisioning

# ルックアップテーブルのインポート時、アクティブ化も同時に行うようにする

`sas.referencedata.activation.activateGlobalVariableOnImport`オプションを有効にする。

<https://go.documentation.sas.com/doc/jp/edmcdc/v_056/edmag/n18wqmqx6oses9n1rgxsb2hdtdml.htm#p0gy0cgi56mr34n1tlaev51z8gzv>

# SAS StudioでDS2コードファイルの動作確認を行う

プレースホルダー名`${PACKAGE_NAME}`を有効なDS2パッケージ名で置き換え、`proc ds2; ～ end;`で括る。

<https://go.documentation.sas.com/doc/ja/edmcdc/v_056/edmug/n10dh0jke5q5uvn1kp4wcrbqypkl.htm#n0jxmwswjlvcwvn1kath1xin4pcl>

**書き換え前**
``` sas
proc ds2;
   package "${PACKAGE_NAME}" /inline;
      method execute(/* 入出力変数 */);
         /* 処理内容 */
      end;
   endpackage;
run; 
quit;
```

**書き換え後**

``` sas
proc ds2;
   package "testCustomCode" /overwrite=yes;
      method execute(/* 入出力変数 */);
         /* 処理内容 */
      end;
   endpackage;
run; 
quit;
```