バッチモード処理のテンプレート

perlでテキストファイルハンドリングして、Rの関数を使ってバッチ処理する必要が多い。perlとRとのやりとりのモジュールなどもあるが、使いにくい。R処理する際のテキストファイルの基準を固定して、雛形を使いまわすこととする。以下のサンプルは、パールでタブ区切りのテキストファイルを作成した上で、Rにそのテキストファイルを読ませ、処理をしたあとに、Rからテキストファイルへ書き出させることとし、Rの起動をperlからsystem関数で実行する。Rのコマンドは、テキストファイルでperlからログ代わりに吐き出させておいたバッチ処理用ファイルとしたものである。
サンプルなので、perlには、簡単な2テキストファイルを作らせ、Rにはそれをread.table関数で読ませて、オブジェクトのコピーを作ったあと、それを、write.table関数で書き出させている。
実行に必要なのは、perl、Rである。実行により作成されるのは

  • 2枚のR入力用テキストファイル("inFile1.txt",inFile2.txt")
  • Rのバッチファイル("batch.r")
  • 2枚のR出力ファイル("outFile.txt","outFile2.txt")
  • Rの実行ログファイル("Rbatch.log")

の計6ファイルである。

#!/usr/bin/perl

####
# perlは、Rで実行するコマンドの管理をする役割を持たせる
# Rで用いる入力データおよび出力データはすべて、テキストファイルとして保存する
# Rはバッチモードで実行する
# Rのバッチファイルをperlが作成する
# Rのバッチモード実行ログをバッチモードで出力する
# Rの実行結果はRからテキストファイルへ保存する
# perlで、Rのコマンド文字列を組む
# Rをバッチモードで起動する
# 

use strict;

&main(@ARGV);
exit;

=head1 main

 ###########################################################
 #
 #      #main関数
 #
 
=cut

sub main(@){

### 入力ファイル
# perlでのテキストファイルの作成
# Rに読ませるファイルとして便宜上フォーマットを統一しておく
# 入力ファイルを適当なディレクトリに適当な名前で作成する
# 入力ファイルは、ハンドリングの便宜上、タブ区切り、ヘッダなしで統一する

open (OUT, ">inFile1.txt");
print (OUT "1\tdef\n2\tcde\n");
close OUT;
open (OUT, ">inFile2.txt");
print (OUT "ABC\t11\nDEF\t22\n");
close OUT;

### Rの入力ファイル指定
# 以下のように本 main()で作成したファイルを指定してもよいし、
# あらかじめ作成作成されていたファイルを与えてもよい


my @inFileR= ("inFile1.txt","inFile2.txt");


### 出力ファイル
# Rからの出力ファイルを適当なディレクトリ名・ファイル名で指定する
my $RbatchLog="Rbatch.log";
my @outFileR=("outFile1.txt","outFile2.txt");

### Rバッチファイルの作成
my $batchFile= "batch.r";#バッチファイル名
my $batch="";#バッチファイルに書き出す文字列変数

### 入力ファイルを入力ファイル名で取り込む部分のコマンド文字列作成
# 入力ファイル名と同名のオブジェクトを作成している

my $input_str="";
for(my $i=0;$i<@inFileR;$i++){
 $input_str .= qq
{
$inFileR[$i] <- read.table("$inFileR[$i]", FALSE, "\\t");
};
}

### Rの処理を定義する。その部分の文字列作成
# R操作の簡単な例として、別名のオブジェクトにコピーしている
my @objR=("inFile1.txt","inFile2.txt");

my $r_process_str="";
for(my $i=0;$i<@objR;$i++){
 $r_process_str .= qq
{
$objR[$i] <- $inFileR[$i]
};
}

### Rのオブジェクトをファイルに書き出す部分の文字列作成

my $output_str="";
for(my $i=0;$i<@objR;$i++){
 $output_str .= qq
{
write.table($objR[$i],file="$outFileR[$i]",append=FALSE,quote=FALSE,eol="\\n",sep="\\t",row.names=FALSE,col.names=FALSE)
};
}

### バッチファイルへ書き出す文字列の完成
$batch .= "$input_str";
$batch .= "$r_process_str";
$batch .= "$output_str";

### Batchファイルへの書き出し
open (OUT, ">$batchFile");
print (OUT $batch);
close OUT;

### Rのバッチモード実行
system("R CMD BATCH --vanilla --no-save $batchFile $RbatchLog ");

}