【R言語&Javascript】Rスクリプトをバッチ実行する(その1)

Rscript.exeを使ったバッチ実行ツールの記事。

コマンドプロンプト上で、次のコマンドで実行できるが、
Rスクリプトのファイルパスや引数情報を毎回手入力するのは面倒なので、
javascriptを橋渡し役として使っている。
(このコマンドだけではログ出力されないので、本記事のバッチではログ出力にも対応)

Rscript.exe [Rスクリプトのファイルパス] [引数1] 

  

使い方は次の通り。

  1. 本記事のコードをJS形式で保存(本記事では「AutoExecファイル」と呼ぶ)。
    ※コード内のRscript.exeは自身の保存先パスに書き換えてください。
  2. Rスクリプト(プログラムファイル)をAutoExecファイルにドラッグ&ドロップ。
  3. javascriptが起動し、バッチ実行。
  4. バッチ実行が完了すると、logファイルが出力される。

f:id:cochineal19:20201121225117p:plain

Rバッチの実行(例)

【バッジ実行のコード】

///--- 関数:ゼロ埋め ---///
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を更新。

【R言語&Javascript】Rスクリプトをバッチ実行する(その2) - こちにぃるの日記

本ブログは個人メモです。 本ブログの内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。