stata-c-plugins について
Stata 向け C/C++ プラグインを開発するためのスキルです。機能の構築や移植を行う開発者向けに、macOS 環境での SDK 利用、安全性、テスト、クロスプラットフォーム配布を扱います。
主な機能
- 01Stata プラグイン SDK のガイド
- 02C/C++ の実装パターン
- 03メモリ安全性とテストの指針
- 04クロスプラットフォームのビルドと配布
- 05Stata .ado のラッパーパターン
活用シーン
- 01既存の C++ ライブラリを使った Stata プラグインの構築
- 02統計パッケージ機能の Stata への移植
- 03macOS、Linux、Windows 向けプラグインの配布
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dylantmoore/ stata-skill --skill stata-c-pluginsインストール後、Claude Code で/stata-c-pluginsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/cpp_plugins.mdpackaging_and_help.mdperformance_patterns.mdtesting_strategy.mdtranslation_workflow.md詳細
Stata C/C++ プラグイン開発
Stata 用の高性能な C/C++ プラグインを構築します。このスキルでは、SDK のセットアップからクロスプラットフォームでの配布までの全ライフサイクルを扱います。統計的な補完、ランダムフォレスト、文字列照合、因果推論のための本番用 Stata プラグインを構築した実経験に基づいています。
このスキルでは、開発プラットフォームとして macOS(Apple Silicon または Intel)を前提としています。 ビルドコマンド、クロスコンパイルのワークフロー、Docker の手順はすべて Mac 向けです。プラグイン自体は 4 つのプラットフォーム(macOS ARM64、macOS x86_64、Linux x86_64、Windows x86_64)すべてを対象としますが、開発環境は macOS です。Linux または Windows 上でネイティブに開発する場合は、コンパイルと Docker のセクションを適宜調整してください。
各タスクへの取り組み方
コードを書く前に、必ずプランモードに入ってください。 適切な計画には、次の内容が含まれます。
- 完全な棚卸し — 構築するすべての機能、オプション、コンポーネント(翻訳の場合:ソースパッケージの API を漏れなく列挙)
- アーキテクチャの決定 — C++ バックエンドをラップするか、一から C を書くか、純粋な Stata にするか
- 関連するリファレンスファイル — このスキルのどのリファレンスファイルに必要な情報が含まれているかを事前に特定し、適切なタイミングで読み込まれるよう、計画の各ステップで明示的に参照してください。
references/translation_workflow.md— 翻訳ワークフロー、テストの転用、忠実度監査の全体像references/testing_strategy.md— テストレイヤー、参照データの生成、レイヤー 0(元のテストを転用)references/performance_patterns.md— pthreads、XorShift RNG、quickselect、事前ソート済みインデックスreferences/packaging_and_help.md— .toc/.pkg/.sthlp のテンプレート、ビルドスクリプトreferences/cpp_plugins.md— C++ のラップ、extern "C"、例外安全性、コンパイル
- フェーズごとの手順と、それぞれの依存関係
- 各ステップの内容: 構築するもの、作成するテスト、次に進む前にレビューの反復を行うこと
- 翻訳プロジェクトの場合: 最後のステップとして忠実度監査を実施(
translation_workflow.mdを参照)
コンポーネント間は順番に、各コンポーネント内は並行して実装してください。 インターフェースが定義されたら、独立したサブタスクを並列のサブエージェントに割り当てます(例:C プラグインの実装、.ado ラッパー、テストスイートを同時に進めます)。作業を統合してテストスイート全体を実行し、次のコンポーネントに進む前にレビューの反復を行います。
各コンポーネントの後にレビューの反復を行ってください。
- デフォルト:理想的には異なるモデル(例:Claude + GPT + Gemini)から、2~3 個のレビューエージェントを並列に割り当て、視点を多様化します。環境で利用可能なマルチモデルツールを使用してください。
- 1 つのモデルしか利用できない場合:レビューの観点を変えて、2~3 個のエージェントを割り当てます(正確性、網羅性、アーキテクチャなど)。異なるプロンプトを使うことで、複数モデルによるレビューの多様性を近似できます。
- 各エージェントは差分、テスト結果、要件をレビューします。指示:「不足、バグ、問題点を列挙してください。すべて正しければ LGTM と伝えてください。」
- 指摘された問題をすべて修正して再度割り当て、全エージェントが LGTM と回答するまで反復します。その後、次に進みます。
まずラップし、新規実装はその後に行います
パッケージを移植する際は、アルゴリズムのコードを書く前に、既存の C/C++ バックエンドがないか必ず確認してください。 多くの R パッケージには src/ に C++ コードがあります。多くの Python パッケージには、Cython や同梱の C/C++ ライブラリがあります。文字列照合、線形代数、ツリーアルゴリズムなどを扱うスタンドアロンの C++ ライブラリも存在します。
C++ 実装がある場合は、それをラップしてください。 アルゴリズムを C で再実装しないでください。ラップすれば、同一の出力(同じコードパス)、本番品質のパフォーマンス、そしてコード量の大幅な削減が得られます。プラグインは、Stata の SDK とライブラリの API をつなぐ薄い extern "C" のグルー層にすぎません。バイナリサイズは問題ではありません。すべてを静的リンク(-static-libstdc++ -static-libgcc)して、バイナリがどのようなサイズになってもそのまま配布してください。Windows で 10~15 MB になっても構いません。ユーザーが気にするのはプラグインのファイルサイズではなく、結果の正確さです。
全体のパターンについては references/cpp_plugins.md を、ワークフローについては references/translation_workflow.md を参照してください。この手法(C++ バックエンドのラップ、複数プラグインのディスパッチ、新しいデータでスコアリングを行うための保存/読み込み)の実例は、プロジェクトの CLAUDE.md の「Example Applications」に記載されているリポジトリで確認できます。
移植プロジェクトでは、さらに次のことも行ってください。元のパッケージのテストスイートとデータを活用し(references/testing_strategy.md の Layer 0 を参照)、Stata 固有のテストを追加で作成し、計画の最後に複数エージェントによる忠実性監査を実施します。ワークフロー全体については references/translation_workflow.md を参照してください。
プラグイン SDK
stplugin.h と stplugin.c を次の場所からダウンロードします:https://www.stata.com/plugins/
この 2 つのファイルは、C コードと Stata の間のインターフェースを定義します。
| 関数/マクロ | 用途 |
|---|---|
SF_vdata(var, obs, &val) | 変数の値を読み取ります(1 始まり!) |
SF_vstore(var, obs, val) | 変数の値を書き込みます(1 始まり!) |
SF_nobs() | 現在のデータセットの観測数 |
SF_nvar() | データセット全体の変数数(プラグイン呼び出し分だけではありません) |
SF_is_missing(val) | Stata の欠損値(.)かどうかを確認します |
SV_missval | 欠損値の定数 |
SF_display(msg) | Stata に情報テキストを表示します |
SF_error(msg) | Stata に赤色のエラーテキストを表示します |
インデックスは 1 始まりです。 変数インデックスも観測値インデックスも、0 ではなく 1 から始まります。ここでのオフバイワンエラーは警告なしに発生し、致命的です。誤った変数のデータを読み取っても、警告は表示されません。
メモリ安全性
プラグインがクラッシュすると、Stata セッション全体が終了します。 保存確認も復旧手段もありません。ユーザーは保存していない作業をすべて失います。これは何よりもまず認識しておくべきことです。
- すべての
malloc()/calloc()の戻り値がNULLでないことを確認します argv[]にアクセスする前にargcを検証します- 開発中は
-fsanitize=addressを付けてビルドします - まず小さなデータでテストし、徐々に規模を拡大します
stata_call()ですべてのメモリを事前確保し、最後に解放します
stata_call() エントリーポイント
すべてのプラグインは 1 つの関数を実装します。プラグインは C++ でも記述できます。エントリーポイントに Stata が認識できる extern "C" リンケージを指定すればよく、それ以外はすべて完全な C++ にできます。既存の C++ コードをラップできる場合(例:R パッケージの src/ ディレクトリ)が、C++ を使う典型的なケースです。複雑なデータ構造や std::thread によるスレッド処理が必要な場合にも、C++ が役立ちます。extern "C" のパターン、例外安全性、コンパイルコマンド、ライブラリのラップなど、実践的な C++ のガイダンスについては references/cpp_plugins.md を参照してください。このファイルの残りの部分では、よりシンプルで標準的な選択肢である C に焦点を当てます。
#include "stplugin.h"
// For C++ plugins, wrap the entry point with extern "C":
// extern "C" {
// STDLL stata_call(int argc, char *argv[]) { ... }
// }
STDLL stata_call(int argc, char *argv[]) {
// 0. Validate arguments BEFORE accessing argv[]
if (argc < 3) {
SF_error("myplugin requires 3 arguments: n_train n_test seed\n");
return 198; // Stata's "syntax error" code
}
// 1. Parse arguments (all strings — use atoi/atof)
int n_train = atoi(argv[0]);
int n_test = atoi(argv[1]);
int seed = atoi(argv[2]);
// 2. Get dimensions
ST_int nobs = SF_nobs();
// CAUTION: SF_nvar() returns ALL variables in the dataset, not just
// the ones passed to `plugin call`. If the .ado creates tempvars
// (touse, merge_id, etc.) the count will be higher than expected.
// Pass the variable count via argv instead of relying on SF_nvar().
int p = atoi(argv[3]); // safer: pass feature count explicitly
// 3. Allocate memory
double *X = calloc(nobs * p, sizeof(double));
double *y = calloc(nobs, sizeof(double));
double *pred = calloc(nobs, sizeof(double));
if (!X || !y || !pred) {
SF_error("myplugin: out of memory\n");
if (X) free(X); if (y) free(y); if (pred) free(pred);
return 909;
}
// 4. Read data from Stata (1-indexed!)
ST_double val;
for (ST_int obs = 1; obs <= nobs; obs++) {
SF_vdata(1, obs, &val); // var 1 = depvar
y[obs-1] = val;
for (int j = 0; j < p; j++) {
SF_vdata(j + 2, obs, &val); // vars 2..nvars-1 = features
X[(obs-1) * p + j] = val;
}
}
// 5. Run your algorithm
int rc = my_algorithm(X, y, pred, n_train, n_test, p, seed);
if (rc != 0) {
SF_error("myplugin: algorithm failed\n");
free(X); free(y); free(pred);
return 909;
}
// 6. Write results back to Stata
for (ST_int obs = 1; obs <= nobs; obs++) {
SF_vstore(nvars, obs, pred[obs-1]); // last var = output
}
free(X); free(y); free(pred);
return 0; // 0 = success
}
戻り値
0— 成功198— 構文エラー(引数が不正)909— メモリ不足601— ファイルが見つかりません- 0 以外の値はすべて Stata エラーを発生させます
.ado ラッパーのパターン
ユーザーが plugin call を直接呼び出すことはありません。.ado ファイルが Stata ネイティブのインターフェースを提供します。
Preserve/Merge パターン
データの一部を対象に処理するプラグインの基本パターンです。
program define mycommand, rclass
syntax varlist(min=2) [if] [in], GENerate(name) [SEED(integer 12345) REPlace]
gettoken depvar indepvars : varlist
if "`replace'" != "" {
capture drop `generate'
}
confirm new variable `generate'
// Mark sample: novarlist ALLOWS missing depvar (critical for imputation)
marksample touse, novarlist
markout `touse' `indepvars' // but DO exclude missing predictors
// Stable merge key — create BEFORE any sorting or subsetting
tempvar merge_id
quietly gen long `merge_id' = _n
// Count subsets
quietly count if `touse' & !missing(`depvar')
local n_train = r(N)
quietly count if `touse' & missing(`depvar')
local n_test = r(N)
// Create output variable (all missing initially)
quietly gen double `generate' = .
// Preserve, subset, call plugin
preserve
quietly keep if `touse'
// Sort if plugin requires it (donors first, test second)
tempvar sort_order
quietly gen `sort_order' = missing(`depvar')
quietly sort `sort_order'
// Call plugin
plugin call myplugin `depvar' `indepvars' `generate', ///
`n_train' `n_test' `seed'
// Save results and restore
tempfile results
quietly keep `merge_id' `generate'
quietly save `results'
restore
// Merge predictions back (update replaces missing with non-missing)
quietly merge 1:1 `merge_id' using `results', nogenerate update
end
update が機能する理由: preserve の前では、generate 変数の値はすべて欠損値です。restore の後も、引き続きすべて欠損値です。update オプションは、欠損値をマージファイルの非欠損値で置き換えます。replace オプションは、それより前に capture drop で処理されるため、マージ時には変数が必ず新しく作成された状態になります。
プラグインのソート規約
重要: プラグインによっては、データが特定の順序(トレーニング行が先、テスト行が後)にソートされていることを前提とします。一方、欠損データを内部で処理するプラグインもあります。ソート順の不一致は、最も危険なバグのひとつです。プラグインが誤ったデータをエラーなしで読み込み、無意味な出力を生成してしまいます。ソート順が一致しないと、プラグインがテスト観測値をトレーニングデータとして、またその逆として扱うため、予測品質が大幅に低下することがあります(相関が 0.99 から 0.38 に低下するなど)。
- プラグインが内部で
SF_is_missing()をチェックする場合:.ado ラッパーでソートしてはいけません - プラグインが
n_train行の連続した行の後にn_test行が続くことを前提とする場合:呼び出し前にmissing(depvar)でソートします
プラグインがどちらのパターンを使うかを記載してください。
プラグインの読み込み(クロスプラットフォーム)
gtools 形式の OS 検出パターンを使用してください。c(os) で OS を検出し、ファイル名のみを組み立てます。ファイル名のみを指定すると Stata の adopath 経由で解決されるため、すべてのプラットフォームで確実に動作します。
/* ---- Load plugin (gtools-style: detect OS, bare filename) ---- */
if ( inlist("`c(os)'", "MacOSX") | strpos("`c(machine_type)'", "Mac") ) local c_os_ macosx
else local c_os_: di lower("`c(os)'")
cap program drop myplugin
program myplugin, plugin using("myplugin_`c_os_'.plugin")
プラットフォームに応じて、myplugin_macosx.plugin、myplugin_windows.plugin、または myplugin_unix.plugin に解決されます。
警告 — findfile と絶対パスは使用しないでください。 次のパターンは Windows で動作しないため、決して使用してはいけません。
* BROKEN — DO NOT USE
capture findfile myplugin.plugin
capture program myplugin, plugin using("`r(fn)'")
findfile は絶対パス(例:C:\ado\plus\m\myplugin.plugin)を返します。Windows では、using() 経由で特定の絶対パスを指定すると、Stata の LoadLibrary 呼び出しが失敗します。gtools 形式のパターンでは、パスなしのファイル名のみを渡し、Stata に adopath 経由で解決させることで、この問題を回避します。これは gtools、ftools、その他の主要なパッケージと同じ方法です。
同様に、各 platform-arch サフィックスを順番に試す、ネストした if/else の連鎖も使用しないでください。これは複数のパッケージで使われていた古いパターンであり、findfile を使う場合は同じ理由で失敗するうえ、脆弱で冗長です。
プラグインのファイル名: pluginname_os.plugin。os には macosx、unix、windows のいずれかを指定します。例:qrf_plugin_macosx.plugin、grf_plugin_windows.plugin。
注: clear all は読み込み済みのプラグイン定義を消去します。テストスクリプトの冒頭で clear all を実行すると、すべての program ... plugin 定義が消えます。再読み込みしてください。
クロスプラットフォームコンパイル
3 つのプラットフォーム向けにビルドします(ARM Mac は Rosetta 経由で x86_64 を実行するため、macOS バイナリは 1 つで十分です)。まず Windows 用のクロスコンパイラーをインストールします:brew install mingw-w64。
| 対象 OS | 出力名のサフィックス | コンパイラー | -D フラグ | リンクフラグ | pthreads |
|---|---|---|---|---|---|
| macOS(ARM64) | _macosx | gcc -arch arm64 | -DSYSTEM=APPLEMAC | -bundle | -pthread |
| Linux(x86_64) | _unix | gcc | -DSYSTEM=OPUNIX | -shared | -pthread |
| Windows(x86_64) | _windows | x86_64-w64-mingw32-gcc | -DSYSTEM=STWIN32 | -shared | -lwinpthread |
すべてのプラットフォームで、リリースには -O3 -fPIC を使用し、開発時には -g -fsanitize=address を追加します。
C++ プラグインの場合: gcc の代わりに g++ を使用します。ライブラリが必要とするバージョンの -std=c++ を追加します(ドキュメントを確認してください。C++11、C++14、C++17 がよく使われています)。ヘッダーのみの C++ ライブラリは c_source/ に配置し、-I. を指定してインクルードできます。Windows と Linux では、必ず -static-libstdc++ -static-libgcc を使用してください。
命名規則:pluginname_os.plugin(例:qrf_plugin_macosx.plugin、grf_plugin_windows.plugin)。os サフィックスは、gtools 形式のローダーが生成する値(macosx、unix、windows)と一致している必要があります。
macOS に関する注意:-shared ではなく、-bundle を使用してください。よくある間違いです。
macOS から Linux へのビルド(Docker が必要)
macOS にはネイティブの Linux クロスコンパイラーがありません。Colima 経由で Docker を使用します(brew install colima docker を実行し、続いて colima start を実行します)。次のワンライナーでビルドします。
docker run --rm --platform linux/amd64 -v "$(pwd):/build" -w /build ubuntu:18.04 \
bash -c "apt-get update -qq && apt-get install -y -qq g++ gcc make > /dev/null 2>&1 && make linux"
glibc 互換性: 最大限の互換性を確保するには、Ubuntu 18.04 でビルドしてください(必要なのは GLIBC 2.14 のみで、2012 年頃以降のあらゆる Linux で動作します)。Ubuntu 22.04 以降でビルドすると GLIBC 2.34 が必要になり、RHEL 8、Ubuntu 20.04、多くの HPC 環境では動作しません。
パフォーマンスの最適化
詳細なコード例については、references/performance_patterns.md を参照してください。
- 事前ソート済みの特徴量インデックス — 特徴量の値を一度ソートし、各ツリーノードで線形にスキャンします。分割ごとに O(n log n) ではなく O(n) です。
- 事前計算した距離ノルム — KNN では、||a-b||^2 = ||a||^2 + ||b||^2 - 2*a'b を活用します。
- クイックセレクト — k 番目に近い近傍を見つけるための O(n) の部分ソートです。
- アンサンブル学習の並列化(pthreads) — 複数のモデルを同時に学習します。各スレッドには専用のデータコピーと RNG 状態を割り当てます。ワーカースレッドから Stata SDK 関数(
SF_vdata、SF_vstore、SF_display)を絶対に呼び出さないでください — まずメインスレッドですべてのデータを読み込み、計算をワーカーに割り当て、結合後にメインスレッドで結果を書き戻します。 - XorShift RNG — C プラグインから Stata の内部 RNG(
runiform())にはアクセスできません。XorShift128+ は高速で統計的に信頼性があり、スレッドセーフです(各スレッドに専用の状態を割り当てます)。再現性を確保するため、argv[]からシードを取得してください。 - ツリー用の密な配列 — キャッシュ局所性を高めるため、リンクリストではなくフラットなノード配列を使用します。
デバッグ
Stata のプラグインホストにデバッガーを接続できないため、デバッグは困難です。
デバッグ方法
-
SF_display() を使った printf:
char buf[256]; snprintf(buf, sizeof(buf), "Debug: n=%d, p=%d\n", n, p); SF_display(buf); -
診断ファイルを書き出す:
FILE *f = fopen("plugin_debug.log", "w"); fprintf(f, "value at [%d][%d] = %f\n", i, j, val); fclose(f); -
まず単体でテストします。 CSV を読み込み、アルゴリズムを呼び出す
main()を作成します。通常のツール(gdb、valgrind、サニタイザー)でデバッグしてから、プラグインインターフェースに適合させます。 -
開発中はサニタイザーを有効にしてビルドします:
-g -fsanitize=address -
SF_vdata() の戻り値を確認します。 戻り値は
RCです(0 は成功)。0 以外の場合、obs/var のインデックスが無効です。
よくある失敗例
| 症状 | 考えられる原因 |
|---|---|
| Stata が何も表示せずにクラッシュする | セグメンテーション違反:バッファーオーバーフロー、不正な argv アクセス、NULL 参照解除 |
| プラグインがすべて欠損値を返す | 変数の数が誤っている、obs のインデックス付けが誤っている、プラグインが読み込まれていない |
| 結果がでたらめになる | ソートの不一致、0 始まりと 1 始まりのインデックスの取り違え、入力が正規化されていない |
| 「plugin not found」 | ファイル名が誤っている、clear all で定義が消去された、プラットフォームが誤っている |
| Mac では動くが Linux では失敗する | 整数サイズの違い。<stdint.h> の int32_t/int64_t を使用してください |
パッケージングと配布
プラットフォームごとに .pkg ファイルを用意し、ユーザーが自分の OS 用のバイナリだけをダウンロードできるようにしてください。Stata の net install に条件分岐機能はないため、すべてのユーザーに 4 つのバイナリを配布せずに済ませるには、プラットフォームごとに個別のパッケージを提供します。すべてのパッケージに同じ .ado ファイルと .sthlp ファイルをインストールし、異なるのは .plugin バイナリだけです。
mypackage/
├── stata.toc # lists all package variants
├── mypackage.pkg # all platforms (for users who don't care)
├── mypackage_mac.pkg # macOS only
├── mypackage_linux.pkg # Linux only
├── mypackage_win.pkg # Windows only
├── mycommand.sthlp # overview help file (short name!)
├── mycommand.ado # user-facing command
├── myplugin_macosx.plugin
├── myplugin_unix.plugin
├── myplugin_windows.plugin
└── c_source/ # NOT distributed, for building
├── build.py
├── stplugin.c
├── stplugin.h
└── algorithm.c
ユーザーは自分のプラットフォーム用のパッケージをインストールします。
* macOS
net install mypackage_mac, from("https://raw.githubusercontent.com/user/repo/main") replace
* Linux
net install mypackage_linux, from("https://raw.githubusercontent.com/user/repo/main") replace
* Windows
net install mypackage_win, from("https://raw.githubusercontent.com/user/repo/main") replace
すべてのプラットフォーム用バイナリは全プラットフォーム対応の .pkg を通じて配布するか、ユーザーがプラットフォーム別のパッケージをインストールできます。Stata は実行時に gtools 方式の OS 検出を使って、対応するプラグインだけを読み込みます。Windows の C++ バイナリは静的リンクのため 10~15MB になることがありますが、これは通常のことです。
.toc、.pkg、.sthlp のテンプレートと SMCL の書式については、references/packaging_and_help.md を参照してください。
よくある落とし穴
-
ソートするとマージキーが壊れます。
preserve/restore内でソートすると、merge_id の関連付けが壊れます。必ずpreserveの前に merge_id を作成してください。 -
すべて 1 起点です。
SF_vdata(var, obs, &val)— var と obs はどちらも 1 から始まります。オフバイワンエラーが発生しても、エラーは通知されません。 -
marksampleはデフォルトで欠損値を除外します。 欠損した従属変数がまさに対象となる補完の場合は、marksample touse, novarlistを使用してください。 -
macOS では
c(os)は "MacOSX" を返します。 Mac の検出には、gtools のパターンであるinlist("c(os)'", "MacOSX") | strpos("c(machine_type)'", "Mac")を使用してください。他のプラットフォームでは、lower(c(os))は"windows"または"unix"を返します。 -
argv[] に境界チェックはありません。
argc == 2のときにargv[3]にアクセスすると、セグメンテーション違反が発生します。必ず先にargcを確認してください。 -
clear allはプラグインを消去します。 テストスクリプトでclear allを実行した後は、プラグイン定義を再読み込みしてください。 -
.ado ファイル内で自動検出されるのは、最初の
program defineだけです。 サブプログラムには個別の .ado ファイルを用意するか、明示的にrunして読み込む必要があります。 -
アルゴリズムで必要な場合は、入力を正規化してください(ニューラルネットワーク、勾配ベースの手法、KNN のような距離ベースの手法)。.ado ラッパーで平均=0、標準偏差=1 にスケーリングし、予測値を処理後に元のスケールに戻してください。プラグインには整った正規化済みデータを渡し、スケーリングは .ado に任せてください。
-
Windows で pthreads を使用するには
-lwinpthreadが必要です。 条件付きのリンカーフラグを使用してください。 -
メモリエラーが発生すると、Stata は復旧せずにクラッシュします。 すべて事前に割り当て、各割り当てを確認し、開発中はサニタイザーを有効にしてビルドしてください。
-
glibc のバージョン不一致。 最新のディストリビューションで Linux プラグインをビルドすると、古いシステムでは読み込めないバイナリが生成されます。最大限の互換性を確保するため、Docker では Ubuntu 18.04 を使用してください。
-
SF_nvar()はデータセットの変数総数を返します。plugin callの変数リストにある変数だけでなく、データセット内のすべての変数を数えます。.ado が一時変数(touse、merge_id、ソートキー)を作成する場合、想定より多い値になります。引数の数を検証するためにSF_nvar()を使用しないでください。代わりに、想定する数をargv経由で渡してください。 -
findfileと絶対パスの組み合わせは Windows で問題を起こします。findfileが返す絶対パスは、Windows 上で Stata のLoadLibraryから解決できません。代わりに gtools 形式の OS 検出パターンを使用してください(上記の「プラグインの読み込み」セクションを参照)。この方法では、Stata が adopath 経由で解決するファイル名のみが生成されます。
命名規則
- 手法選択オプションには
model()ではなくmethod()を使用する - 出力変数の命名には
generate()(省略形gen())を使用する replaceはreplace()ではなくフラグオプションとして使用する- プラグインファイル:
algorithm_plugin_os.plugin。os はmacosx、unix、またはwindows - .ado ファイル:小文字を使い、複数語にはアンダースコアを使う
- Stata のオプション規則:オプションは小文字、省略形は大文字で始める(
GENerate、MAXDepth) - プラグインをサポートする Stata 14.0 以降を対象にする(
version 14.0) - ヘルプファイルにはリポジトリ名ではなく、短いコマンド名を使用します。 リポジトリ名が
mypackage_stataの場合でも、概要ヘルプファイルはmypackage.sthlpにしてください(これによりhelp mypackageが機能します)。ヘルプファイル名やコマンド名に「stata」を付けないでください。ユーザーはすでに Stata を使っています。