データを取り込む
データの入力は表計算ソフトを使うのが便利です。
入力ができたら,表計算ソフトのワークシートから直接コピーして処理ができます。
また,データのやり取りなどでCSVに書き出した場合は,テキストエディタで開いてコピーします。
CSV形式とは,1行分のデータをコンマで区切り,行末で改行したものです。
この節では表計算ソフトでデータを入力してKeTCindyにそれを取り込む方法を説明します。サンプルデータは,このページの下部からダウンロードできます。
データの入力とコピー
次の図は,表計算ソフトに入力したDNAについて,塩基の割合を示した表です。(リードα生物基礎 数研出版)
A1セルからE6セルまでを選択し,Ctrl+C (Macは command+C) で記憶し,Cindyscriptエディタ上でInitializationスロットのフォルダアイコンをクリックして新しいページを作り, Ctrl+V で貼り付けると次のようになります。文字は黒で表示されます。
スペースで区切られているように見えますが,実際にはtabコードで区切られています。行末には改行コードが入っています。
この全体を data=""; の中にいれて文字列にします。
先に data=""; を書いておいて,その中に Ctrl+V で貼り込んでも構いません。
これを2次元のリストにします。
dlist=tokenize(data,unicode("0A"));
で改行コードで区切ってリスト化し,それぞれの要素を
dlist=apply(dlist,tokenize(#,unicode("09")));
でtabコードで区切ります。
Drawスロットで println(dlist) を実行すると,コンソールに次のように表示されてリスト化されたことがわかります。
[[,A,T,G,C],[トリ結核菌,15.5,14.3,36.4,33.8],[大腸菌,24.7,23.6,26,25.7],[コムギ,27.4,27.1,22.7,22.8],[サケ,29.7,29.1,20.8,20.4],[ヒト,30.9,29.4,19.9,19.8]]
このように,tokenize() を使って,コピーしたデータをリスト化することができます。
ところで,KeTCindyにはこれをおこなう関数 Tab2list() が用意されています。したがって,
dlist=Tab2list(data);
とすれば,1行でリスト化できます。
CSV データの読み込み
表計算ソフトから CSV に書き出すと,次のようなテキストデータができます。
,A,T,G,C
トリ結核菌,15.5,14.3,36.4,33.8
大腸菌,24.7,23.6,26,25.7
コムギ,27.4,27.1,22.7,22.8
サケ,29.7,29.1,20.8,20.4
ヒト,30.9,29.4,19.9,19.8
このデータは表計算ソフトで開いて,各セルに割り当てることができます。
また,CSV形式では,文字列を " でくくって
,"A","T","G","C"
"トリ結核菌",15.5,14.3,36.4,33.8
"大腸菌",24.7,23.6,26,25.7
"コムギ",27.4,27.1,22.7,22.8
"サケ",29.7,29.1,20.8,20.4
"ヒト",30.9,29.4,19.9,19.8
とすることもあり,これでも表計算ソフトで読み込めます。
CSVに書き出したものはテキストファイルなので,テキストエディタで開いてCindyscriptエディタ上に Ctrl+V で貼り付けることができますが,Readcsv() を使うとそのままデータとして読み込むことができます。
表計算ソフトから書き出したデータを DNA.csv としましょう。これを作業フォルダ(fig) に置き,
dlist=Readcsv("DNA.csv");
とすれば読み込まれます。println(dlist) で確かめてみましょう。
なお,ちょっとした注意があります。Cinderellaが扱う文字コードの体系はUnicodeです。
ですから,読み込む CSVファイルは Unicode(UTF-8) になっている必要があります。
Macの場合は標準がUnicode なので,気にする必要はほとんどありませんが,Windowsの場合は注意が必要です。
Shift-JIS の場合は,次のように日本語が文字化けします。
また,Readcsv() では,文字列を "文字" としていると,ダブルクォーテーションも有効にするので,あらかじめテキストエディタで削除しておくとよいでしょう。
データの表示
コンソールではなく,Cinderellaの描画面にデータを表形式で表示します。
dlist=Readcsv("DNA.csv");
rown=length(dlist);
coln=length(transpose(dlist));
Yoko=[30]++apply(1..(coln-1),20);
Tate=apply(1..rown,10);
Tabledatalight("",Yoko,Tate,[],[0,"Rng=n"]);
repeat(rown,s,Putrow(s,"c",dlist_s));
YokoとTateはセルの横と縦の長さ指定です。1列目だけセル幅を大きくする必要があるので,
Yoko=[30]++apply(1..(coln-1),20);
としています。
Tabledatalight() の第2オプションで,0はラベルを非表示にし,"Rng=n" は出力範囲の NE,SWをフリーにするものです。"Rng=n" をつけなければ,表の右上がNE,左下がSWになるので,それでも構いません。
表の数字の中で,大腸菌のGだけ,小数点以下第1位が0なので,表示されていません。これを 26.0 にするには,ちょっとした工夫が必要です。
repeat(・・・) のデータ表示部分を次のように変えます。
まず,タイトル行と列を先に表示し,中身は小数点以下第1位に整形して表示します。
それぞれの数値はSprintf() を使って整形します。数値のセルは,2行目の2列目からです。
repeat(rown-1,s,start->2,
forall(2..coln,Putcell(#,s,"c",Sprintf(dlist_s_#,1)));
);
この例では,データは5行ですが,もっと多くなった場合は表示しきれませんので,表計算ソフトと同様にスクロールしながら表示する必要があります。
そのためには,スライダを作って,表示範囲を指定します。次はその一例です。
Slider("A-C-B",[-2,10],[-2,0]);
dlist=Readcsv("seiseki.csv");
rown=length(dlist);
coln=length(transpose(dlist));
Yoko=[30]++apply(1..(coln-1),20);
Tate=apply(1..11,10);
Tabledatalight("",Yoko,Tate,[],[0,"Rng=n"]);
Putrow(1,"c",dlist_1);
st=min([rown-10,floor(|A,C|/|A,B|*rown)+1]);
repeat(10,s,start->2,
Putrow(s,"c",dlist_(st+s-1));
);
インデックスの分離
2次元のCSVデータでは,1行目や1列目を項目名に使っている場合が多いでしょう。これらをインデックスと名付けておきます。
先ほどのDNAのデータでは,1行目,「(空) ,A,T,G,C」 がDNAの塩基の名称,1列目 「トリ結核菌,・・ 」が細胞の名称です。
これらインデックスがない場合もありますので,一律に処理することはできませんが,集計などの処理のためには,インデックスとデータ部分を分離しておくと便利な場合があります。そこで,インデックス以外を取り出したリストを作ります。
リストの要素にアクセスする演算子 _ (アンダーバー)では,アクセスする要素の番号をリストにすると,まとめて要素を取り出すことができます。インデックス行は1番目のリストですから,2番目から最後までを取り出せばよいわけです。
datalist=Tab2list(Orgdata,["Sep=,"]);
rown=length(datalist); // 行数
datalist2=datalist_(2..rown);
また,リスト処理の関数に,n番目の列だけを取り出す関数 column(list,n)があります。したがって,2番目から最後までの列を取り出せば転置行列を使わずにインデックス列が分離できます。
colindex=column(datalist,1); // 列インデックス
取り出す列の番号はリストにはできないので,2列目からあとを取り出すには,ちょっとしたテクニックが必要です。
リストの各要素に対してある操作をした結果をリストとして返す apply() を使います。
work=apply(2..coln,column(datalist2,#));
data=transpose(work);
表計算ソフトに逆コピー
KeTCindyで処理したデータは,Dispmat()関数を用いると,Tab区切りでコンソールに表示されます。
これをコピーアンドペーストで表計算ソフトのワークシートに貼り込むことができます。
CSVへの書き出し
データをCSVに書き出すには,Writecsv(namelist, data, filename, option) を用います。
namelist は1行目のインデックス,data がデータリストです。先ほどのDNAのデータの場合,
Writecsv("",dlist, "DNA2");
のようにするのが簡明でしょう。書き出された DNA2.csv ファイルは(作業フォルダ:fig にあります)
c1,c2,c3,c4,c5
"","A","T","G","C"
"トリ結核菌",15.5,16.5,36.4,33.8
"大腸菌",24.7,23.6,26,25.7
"コムギ",27.4,27.1,22.7,22.8
"サケ",29.7,29.1,20.8,20.4
"ヒト",30.9,29.4,19.9,19.8
となるので,先頭の行をテキストエディタでカットします。