RのGUI

Rのグラフ作成支援

しばらくRネタが続いているが、その理由は、測定をしながらグラフを書くためのツールを作っていて、そのために必要なRのテクニックを学んでいたからだ。ようやく、多少は使えるものができたので、homepageに公開した。まあ、誰が使ってくれるわけでは無いとは思うが、測定用のPCにそのファイルを取ってくるときに、自分が便利にはなるだろう。

必要なルーチンは三つのファイルに分割した。一つは先に紹介したtktool.rで、tcltkを自分なりに使いやすくしたものだ。グラフの描画のデータ構造はplot.rに記述した。そして、GUI部分はgraphtk.rにまとめた。こうゆうプロクラムは、GUI部分が一番面倒である。実際、ファイルサイズも大きい。使うときには、

source("graphtk.rb")

として、出てきたメニューから使用する。以前使っていたigorに少しだけ影響を受けている。まだ最小限の機能しか使えないし、おそらくバグもあるだろう。imageやrglも機能限定ながら使えるようにしてみた。

このプログラムの前身として、rsrubyとrubytkを使って、rubyで書いたものがあった。昔の記録を見ると、2006年ぐらいには作っていたようだ。しかし、rsrubyでは描画したグラフが別のwindowが上を通ったときに消えたり、debianにrsrubyをうまくインストールできなかったり、という問題が生じてきて、あまり使えなかった。そして、2008年にRから直接tcltkを使ってGUIを作ろうと思って、書き始めてはいたが、Rではrubyのように思ったことが簡単に実現できないので、途中でしばらく放置してあった。最近、Rの知識も増えてきたので、思い出したように作っていたのだ。

ツールとしては使いやすくなったのだが、いろいろなグラフを一つのデータ構造で記述するには、なかなか工夫を必要とした。少し汚いやり方もしている。また、まだできないことも多い。上下に分割したグラフや、labelの位置調節など、コマンドラインからは簡単にできるのだが、それにGUIをつけるのは、非常に面倒だ。

一応beta versionが完成したので、しばらく使ってみて、気が向いたら機能を拡張していこう。

Read more...

オブジェクトの活用

Rとtcltk

Rでは、require(tcltk)とすれば、tkが使えるようになる。しかし、tkのコマンドはあまり馴染みが無いので、なかなか使いにくい。これが多少は使いやすくなるように、ツールを作って、個人的に利用している。しかし、気に入らない点がある。それは、tkで入力した値を取り出すときの方法が統一的ではないということである。tclVarのときには、tclvalue()で値を呼び出す。一方、tklistboxは、tkcurselection()を使って選ばれているものを取り出す。本当はどれでも同じ関数で値を取り出したい。

そこで、tclvalueを調べてみると、UseMethod("tclvalue")となっている。つまり、オブジェクトの種類によって、実行されるメソッドが違うのだ。そこで、attr(,"class")をつかってクラス名を調べると、tclVarはそのままtclVarで、tklistboxはtkwinとなっている。他のtkのオブジェクトもtkwinであるようだが、値を呼び出す必要があるのは、listboxだけなので、次のように定義した。

tclvalue.tkwin <- function(x) as.integer(tkcurselection(x))

こうすると、tclvalue()でtklistboxを呼ぶと、tkcurselection()が呼ばれて、値が取得できるのだ。

これで、tclvalue()のみで値の取得ができるようになった。残る問題は値の代入だ。tclVarはtclvalue(x)<-1などで値を設定できるが、当然tklistboxではだめだ。値を代入できるような関数をどのように書くかが分からない。一つの解決策としては、全く別のメソッドをつくってしまって、例えば、my_set(x,1)とすると、値が代入されるようにして、my_set.tclVarとmy_set.tkwinを定義する方法がある。しかし、tclvalue(x)<-1という形でできるようにできないのかな。

Read more...

オブジェクト指向言語R(uby)

Rのオブジェクトプログラミング

Rはオブジェクト指向の言語らしい。しかし、どのように書くとオブジェクト指向っぽくなるのかよく分からない。The R language definitionを少し読んで、どのように使うのかを調べてみた。

まず、オブジェクトのクラスを指定するためには、"class"という属性に文字列で指定するだけでよい。したがって、どんな名前のクラスにもできる。

a<-2
attr(a,"class")<-"num"
b<-"2"
attr(b,"class")<-"str"

次に、オブジェクト毎に、異なった挙動をするメソッドを定義する必要がある。これは、UseMethodを使って、関数名とオブジェクト名をピリオドでつないだ関数を自動的に呼ぶようにすることで実現する。

dub<-function(x) UseMethod("dub")
dub.default<-function(x) x
dub.num<-function(x) 2*x
dub.str<-function(x) paste(x,x,sep="")

こうすると、dub(a)を呼び出すと4が、dub(b)を呼び出すと"22"となる。

しかし、rubyのように、インスタンス変数を定義して、それに値を代入したり、いろいろなデータ構造を持たせるにはどのようにすれば良いのかよく分からない。Rのオブジェクト指向を使った良い例が見つかると分かりやすいのだが、まだ見つけていない。

Read more...

Rのベクトル

Rのdeparse()の挙動
deparse()をつかってプログラムを書いていたら、なんだか思ったように動かない。原因を調べていたら、長いデータをdeparse()すると、ベクトルになって返ってくることが原因だった。Rでは、ベクトルの処理は独特である。例えば、c(1,2,3,4)+c(4,5)は、5 7 7 9となり、c(1,2,3,4)+c(4,5,4,5)と解釈される。このような挙動のために、変になっていた。paste(deparse(),collapse="\n")で、一つの文字列にすると、問題なく動いた。

Read more...

オブジェクトの保存

Rのdeparse
Rのオブジェクトをファイルに保存する方法を考えていたのだが、deparse()を使うと良いようだ。

d<-list(1, 2, c(1, 2, 3))
deparse(d)

とすると、そのまま"list(1, 2, c(1, 2, 3))“となる。つまり、この頭に"d<-“をつければ、そのオブジェクトを作るコードが保存できることになる。なるほど。

Read more...

Rのオブジェクト

ベクトルとスカラー、リストとデータフレームの違い
Rはグラフソフトとして使っていて、これまで言語としてとらえていなかった。また、一貫して勉強したことが無いので、その言語の特徴をいまいち理解していない。しかし、くせはあって組みにくいけど、なかなかおもしろい言語のように思えてきたので、少しずつ勉強していけたらと考えている。 Rには様々なオブジェクトがあるが、どれだけの種類があるのだろう。オブジェクトの種類は、typeof()で調べることができる。 Rのオブジェクトにベクトルがあるが、これにはさらに五つの型があって、異なる型のデータを入れることはできない。つまり、c(1,“2”)とはできない。実は、スカラーもベクトルと考えているようだ。‘1’[1]としたら"1"が返ってきたし、“1”==c(“1”)はTRUEとなる。 異なる型を配列にできるオブジェクトとしては、リストがある。また、それぞれの要素には成分名をつけることができるので、連想配列のように使うこともできる。例えば、d<-list(a=1,b=2)としておけば、d[[1]]でも良いが、d$aでもアクセスできる。ファイルからデータを読み込むときにつくるデータフレームにアクセスの仕方が似ていると思って、試しにデータフレームをtypeof()で調べてみたら、listとなった。つまり、データフレームはリストだったようだ。しかし、d<-list(a=c(1,2),b=3)とすると、d$bは当然3になるが、d<-data.frame(a=c(1,2),b=3)とすると、d$bはc(3,3)となる。厳密には多少違うようだ。 まだまだ勉強する必要がありそうだ。

Read more...

R言語

Rの環境

Rでグラフを書きながら、測定の様子を観察していると、待っているときに、Rで楽にグラフが書けるようにRをいろいろといじってしまう。言語としてのRは、それなりに興味深い仕様になっている。

関数を定義すると、その中で定義された変数はローカルになる。しかし、外の変数を読むこともできるので、その変数がどの変数なのかが分からなくなってしまう。変数をすべてグローバルにしてしまえば、ややこしくはなくなるが、どうしても変数名が重複する可能性が出てくるので、変数はローカルであるべきだ。

次のような例を考えてみよう。

x<-1
test<-function(){
  cat(x)
  x<-2
  cat(x)
}
test()
cat(x)

この実行結果は121となる。testという関数が呼ばれて、最初にxを見ると、関数の外で定義されたxの値となり、関数の中で代入するとその値になる。そして関数の外で見ると、元の値になっている。つまり、関数の中の一個目と二個目のxは別のxになっているのである。

こうなってくると、関数から外の変数の値が見えるのが、便利なのか不便なのかが分からなくなってくる。

このような場合には、関数内だけの環境を作って、その環境を指定して変数に代入したり呼び出したりすればよい。長くなるけど、こんな感じになる。

x<-1
test<-function(){
  cat(x)
  testenv<-new.env()
  assign("x",2,env=testenv)
  cat(get("x",env=testenv))
}
test()
cat(x)
これで、xの意味合いがはっきりとする。しかもtempenvは関数の中のローカル変数なので、外からは見えない。でも、面倒だな。
Read more...

敗退か?

液晶ディスプレイの修理
本日、ある人から、液晶の割れたディスプレイを頂いた。これで、手元にある故障している液晶ディスプレイが三台となった。通常、壊れたものが三つあれば、うまく組み合わせれば、二つぐらいはうまく動くものが作れる。というわけで、部品を入れ替えて、ディスプレイの復活を試みた。 割れた液晶パネルを、別の液晶パネルと入れ替えれば、とりあえず一台は復活するはずである。しかし、そう単純では無かった。一台はbenq、一台はSharpで、もう一つはIODATAと、三つともかなり違うメーカーのものだった。液晶パネルの大きさが微妙に違うのである。どれも同じ19インチだったので、共通の規格だろうと思っていたら、縦横と厚さも違っていて、うまくいかない。それならばと、液晶パネルを分解して、最前面の液晶板だけを入れ替えようとしたが、これも厚さの違いによって挫折。最終的には液晶パネルと筐体の間にできた隙間にスペーサーをつめて、強引に組み立てた。なんとか一台は復活したが、納得がいかないやり方になってしまった。 最後の一台の部品も流用できないかも検討したのだが、これはまた規格が違っていた。通常は上部にあるコネクタが下部にあり、さらに陰極管のコネクタも他のものとは違っている。互換性という意味では、他のパネルとは入れ替えることができない。 三台から二台を復活させるつもりだったが、中途半端な一台だけしか復活させることができなかった。微妙に敗退感がある。

Read more...

Rのコマンド

Rでファイルの読み込み

グラフを書くときに使っているRだが、プログラム言語としてもそれなりに使える。統計的な計算を含んだ簡単なプログラムの場合には、別の言語でその統計処理のルーチンを書くよりも、Rに元からある関数を使う方が早い場合がある。

しかし、Rの目的は通常のプログラムを作ることではないので、他の言語では簡単にできることが、Rではどのようにしたら良いのか分からない場合もある。その一つがファイルからのデータの読み込みである。data frameにデータを取り込む場合には、read.tableを使ってやっているが、通常の文章などのファイルを読み込む方法がこれまで分からなかった。もしあるとすれば、readなんとかという関数だろうと思って、help.search("read")としてみると、readLinesというのがあって、ファイルの内容を行単位で読み取ることができる関数を見つけた。Rではもっといろいろなことができるのだろうが、良いリファレンスマニュアルは無いのかな。

Rubyではこのmethodを使えば良いということが分かっても、それと同じことをするRの関数が分からないとプログラムを書くのに四苦八苦してしまう。試しに、文字列操作の関数のRubyとRの対応表をつくってみよう。

R Ruby
paste(x,y,sep="") x+y or a.join("")
substr(x,start,stop) x[start..stop]
sub(pattern,replacement,x) x.sub(pattern,replacement)
gsub(pattern,replacement,x) x.gsub(pattern,replacement)
strsplit(x,split) x.split(split)
ほんの一部のコマンドしか書いていないが、意外にrubyであるmethodに対応した関数はRにもかなりあるように思う。他のコマンドもhelp.search("string")などで探して使ってみようかな。

2010/8/31追記 rubyのa.join("")に対応するのは、Rのpaste(a,collapse="")かもしれない。

Read more...

ARM機

ちょいパソ
久しぶりにパソコン工房のhomepageを見ていたら、「ちょいパソ」というものを見つけた。ARM9を搭載して、600gで一万五千円程度である。ディスプレイは七インチで800*480とまあまあである。また、USBポートもある。非常に魅力的に感じたか、致命的なのがOSで、WindowsCEである。これをlinuxかBSDで動かすことができれば、買いなのだが、少し検索したところ、まだ情報はあまり無いようである。いずれはだれかがやってくれるだろうが、それまでは待ちかな。 以前、mobile gearIIにNetBSDを入れてしばらく使っていたが、emacsなどを立ち上げると、かなり遅く感じた。最近はめっきり使っていないが、まだ可愛いので捨てるのを躊躇している。sharpのNetWalkerZ1が出たときには、linuxだったので、良かったのだが、キーボードの評判が良く無かったので、見送った。しかし、次に出たT1では、キーボードが改良されるのではなく、無くなってしまったので、購入候補からは完全に外れてしまった。ちょいパソの今後に期待できると良いのだが。

Read more...