Rscript.exeを使ったバッチ実行ツールの記事です。
コマンドプロンプト上で、次のコマンドで実行できますが、
Rスクリプトのファイルパスや引数情報を毎回手入力するのは面倒なので、
javascriptを橋渡し役として使っています。
(こちらのコマンドだけではログも出力されないので、本記事のバッチではログ出力にも対応しています。)
Rscript.exe [Rスクリプトのファイルパス] [引数1]
使い方は次の通りです。
- 本記事のコードをJS形式で保存します(本記事では「AutoExecファイル」と呼びます)。
※コード内のRscript.exeは自身の保存先パスに書き換えてください。 - Rスクリプト(プログラムファイル)をAutoExecファイルにドラッグ&ドロップします。
- javascriptが起動し、バッチ実行を開始します。
- バッチ実行が完了すると、logファイルが出力されます。
【バッジ実行のコード】
///--- 関数:ゼロ埋め ---///
function ZeroPadding(tval){
return('00'+tval).slice(-2);
}
///--- ドラッグ&ドロップされたファイル名を取得 ---///
if (WScript.Arguments.Count() != 1){
WScript.Echo('Rスクリプトファイルをドラッグ&ドロップしてください');
WScript.Quit();
} else if (WScript.Arguments.Item(0).slice(-2).toLowerCase() != '.r') {
WScript.Echo('Rスクリプトファイル以外をドラッグ&ドロップされました');
WScript.Quit();
}
///--- Rscript.exeがなければ処理中止 ---///
var fso = WScript.createObject('Scripting.FileSystemObject');
var Rscript_exe = 'C:/Program Files/R/R-4.0.1/bin/Rscript.exe'; // ここにRscript.exeのパスを指定。
if (!fso.FileExists(Rscript_exe)) {
WScript.Echo('Rscript.exeが見つかりません。\n - 確認先パス:' + Rscript_exe);
fso = null;
Rscript_exe = null;
WScript.Quit();
}
///--- Rスクリプト情報の取得 ---///
var RscriptPath = WScript.Arguments.Item(0).replace(/\\/g, '\/')
var RscriptFolder = fso.GetParentFolderName(RscriptPath)
var RscriptName = fso.GetFileName(RscriptPath)
///--- 日付取得 ---///
var now1 = new Date();
var now2 = now1.getFullYear() +
ZeroPadding(now1.getMonth() + 1) +
ZeroPadding(now1.getDate()) +
'_' +
ZeroPadding(now1.getHours()) +
ZeroPadding(now1.getMinutes()) +
ZeroPadding(now1.getSeconds())
;
var now3 = now1.getFullYear() + '年' +
ZeroPadding(now1.getMonth() + 1) + '月' +
ZeroPadding(now1.getDate()) + '日' +
' ' +
ZeroPadding(now1.getHours()) + '時' +
ZeroPadding(now1.getMinutes()) + '分' +
ZeroPadding(now1.getSeconds()) + '秒'
;
///--- 出力ログファイル名 ---///
var LogName = RscriptFolder + '/__log_' + fso.GetBaseName(RscriptPath) + '_R_' + now2 + '.log';
///--- 実行 ---///
var wsh = WScript.createObject('WScript.Shell');
var cmd = 'echo ' + RscriptName + ' を実行中です。しばらくお待ちください。';
var cmd = cmd + ' & echo カレントディレクトリ:' + RscriptFolder;
var cmd = cmd + ' & echo ----------------------------------------------------------------------------------- > ' + LogName;
var cmd = cmd + ' & echo 対象ファイル:' + RscriptPath + ' >> ' + LogName;
var cmd = cmd + ' & echo 実行日時 :' + now3 + ' >> ' + LogName;
var cmd = cmd + ' & echo ----------------------------------------------------------------------------------- >> ' + LogName;
var cmd = cmd + ' & "' + Rscript_exe + '" --slave --vanilla ' + RscriptPath + ' "' + RscriptFolder + '" ' + ' __error.txt >>' + LogName + ' 2>&1';
var cmd = cmd + ' & echo -- >> ' + LogName;
var cmd = cmd + ' & echo ----------------------------------------------------------------------------------- >> ' + LogName;
var cmd = cmd + ' & echo End of File >> ' + LogName;
var cmd = cmd + ' & echo ----------------------------------------------------------------------------------- >> ' + LogName;
var cmd = cmd + ' & echo 終了しました。 & pause';
wsh.run('cmd /c ' + cmd);
///--- 後始末 ---///
fso = null;
Rscript_exe = null;
RscriptPath = null;
RscriptFolder = null;
LogName = null;
now1 = null;
now2 = null;
now3 = null;
wsh = null;
cmd = null;
ごちゃごちゃと長く書いていますが、次のコードが肝です。
Rscript_exe + '" --slave --vanilla ' + RscriptPath + ' "' + RscriptFolder + '" ' + ' __error.txt >>' + LogName + ' 2>&1';
分かりやすく書くと次の通り。冒頭で説明したコマンドにオプションやログ出力の設定などを加えています。
Rscript.exe --slave --valilla [Rスクリプトのファイルパス] [引数1] [ログの受取ファイル名] >> [ログファイル名(ここはコマンドプロンプトでの処理)] 2>&1
解説
[Rスクリプトのファイルパス]:
Rコードを書いたファイル(.r形式)のフルパスです。ドラッグ&ドロップしたファイルから自動取得します。
[引数1]:
Rスクリプトが保存されているフォルダパスを文字列として設定します。本パスはグラフ等の出力先としてR内の処理で活用します。こちらも自動取得します。
(Rスクリプト内のコード(引数の受け取り方)は次の記事に移ります。)
[ログの受取ファイル名]:
Rスクリプト内で発生するWarningやErrorメッセージ等を受け取ります。テキスト名は何でも良いです。
※[ログの受取ファイル名]を書かないとログに何も出力されません。
[ログファイル名] 2>&1:
コマンドプロンプト経由で、[ログの受取ファイル名]の内容を[ログファイル名]に掃き出します。[ログファイル名]は年月日_時分秒で自動生成します。
※2>&1 を書かないとコマンドプロンプト画面(黒い画面)にログが出るだけで、[ログファイル名]に書き出しができないようです。
なお、オプション指定に--vanillaをつけておくと、前回閉じたときのデータを保持せずにRを起動します。これをつけないと予期しない結果が返ってくるリスクがありますので、つけておくべきです。
ということで、その1はここまで。
記事その2を更新しました。