yuu_nkjm blog
2010-07-15(Thu) [長年日記] 編集
[R言語] Rのコードが書かれた文字列を評価(eval)する
イディオム
eval(parse(text="評価対象文字列"))
使用例
データフレームxのSEX,HEIGHT,WEIGHTというベクトルに対してsummary関数を適用する.
sex <- c("F","F","M","M","M");
height <- c(158,162,177,173,166);
weight <- c(51,52,72,57,64);
x <- data.frame(SEX=sex, HEIGHT=height, WEIGHT=weight);
i=1
z <- as.list(NULL)
for(col in c("SEX","HEIGHT","WEIGHT")){
z[[i]] <- eval(parse(text=paste("summary(x$",col,")",sep="")))
i=i+1
}
z
> [[1]]
> F M
> 2 3
> [[2]]
> Min. 1st Qu. Median Mean 3rd Qu. Max.
> 158.0 162.0 166.0 167.2 173.0 177.0
> [[3]]
> Min. 1st Qu. Median Mean 3rd Qu. Max.
> 51.0 55.0 57.0 59.8 64.0 72.0
注意1
どういうコンテキストでevalが行われるのか良く分からないと言う人は,"eval.parent"といったキーワードでググってみると良いかも.
注意2
上記のサンプルコードのforループ内で,
という様には書けないけど,
summary(x$col)
とは書けるので,良い例ではなかったな.
summary(x[[col]])
参考ページ
2010-07-14(Wed) [長年日記] 編集
[R言語] Rでベクトル内の重複した要素を取り除く&Rでベクトル内の要素をソートする
Linuxで使うuniqコマンドやsortコマンドに近いことをしたい.そういうときは,unique関数とsort関数が使える.
イディオム
unique(x)
sort(x)
使用例
単純に重複の削除とソートをした例.
x$id
> [1] 22 10 11 12 21 20 90 92 91 10 22 11 12 21 20 203 339 121 90 92 91
unique(x$id)
> [1] 22 10 11 12 21 20 90 92 91 203 339 121
sort(unique(x$id))
> [1] 10 11 12 20 21 22 90 91 92 121 203 339
データフレームxの中のデータをidによって切り出して,valueをプロットする例.
for(targetId in sort(unique(x$id))){
z <- subset(x, id==targetId)
plot(z$time, z$value, xlab = "", ylab = "", axes=F);
par(new = T);
}
まあ,これだと線が一色しかないし,XY軸も書いてないので,使い物にはならないんだけど.
参考ページ
2010-07-13(Tue) [長年日記] 編集
[Java] Javaでapache.commons.lang.SerializationUtils.clone()を使ったディープコピー(Deep Copy)
ディープコピー(Deep Copy)とシャローコピー(Shallow Copy)の区別がつかずにやられるのは誰もが通る道.標準ライブラリを使って自前で実装するのもありだけど,apache.commons.lang.SerializationUtils.clone()を使うのが簡単っぽい.こちらのページには,シャローコピーの例も出ている.
deepCopy関数の内側でキャストするのも良いと思うけど,DataManagerクラス内で,いろんなオブジェクトのdeepCopyをしたかったので,キャストはdeepCopy関数の外側にした.これだと,SerializationUtils.clone()を直接呼ぶのと変わらないんだけど,何をしているかを自分にとって分かりやすくしたかった.
import org.apache.commons.lang.SerializationUtils;
import java.io.Serializable;
public class DataManager {
private EleSimulationState simulationState;
private List histories;
public void finalizeSimulationState() {
histories.add(simulationState);
this.eleSimulationState = (SimulationState) deepCopy(this.simulationState);
}
public Object deepCopy(Serializable state) {
Object dest = SerializationUtils.clone(state);
return dest;
}
}
cloneする対象はSerializableをimplementsする.
public class SimulationState implements Serializable{
private Map<Id, Facility> facilities;
private Map<Id, Vehicle> vehicles;
}
cloneする対象のメンバ変数に含まれるクラスはSerializableをimplements(interface定義ならextends)する.
public interface Facility extends Serializable{}
public interface Vehicle extends Serializable{}
シリアライズ(直列化)の対象から外したいメンバ変数には,transientという修飾子をつける.
参考文献
XStreamを使ったdeep copy
com.thoughtworks.xstream.XStreamというライブラリでもディープコピーが出来るらしい.以下のページには,「XStreamなら、対象のオブジェクトがSerializableを実装していなくても書き出せるのがポイントですね。」と書かれている.