線分データの数え上げ(続きの続きの続き)
前の記事はこちら
今、N個のデータが得られるとする。そのデータは、1次元尺度上の線分に相当するデータであるものとする。簡単に言えば、aiからbiまでというようなデータが、N個得られるとする。このようなデータから、ある値xについて、[tex:ai<=c
test<-function(file){
d<-read.table(file=file)
start<-c(d$V1)
end<-c(d$V2)
startend<-c(start,end)
value<-c(rep(1,length(start)),rep(-1,length(end)))
mat<-matrix(c(startend,value),ncol=2)
matb<-matrix(rep(1,length(startend)^2),ncol=length(startend))
matb[upper.tri(matb)]<-0
order<-order(mat[,1])
accum<-matb %*% mat[order,2]
retmat<-matrix(c(mat[order,1],accum),ncol=2)
return(retmat)
}行列を使わずにループを使うと
test2<-function(file){
d<-read.table(file=file)
start<-c(d$V1)
end<-c(d$V2)
startend<-c(start,end)
value<-c(rep(1,length(start)),rep(-1,length(end)))
mat<-matrix(c(startend,value),ncol=2)
order<-order(mat[,1])
accum<-rep(1,length(startend))
accum[1]=mat[order,2][1]
for(i in 2:length(startend)){
accum[i]<-accum[i-1]+mat[order,2][i]
}
retmat<-matrix(c(mat[order,1],accum),ncol=2)
return(retmat)
}線分の始点・終点の向きを考慮しない場合と、考慮してある向きだけについて加算する、などとするための条件を入れると
test3signPN<-function(file,pn){
d<-read.table(file=file)
start<-c(d$V1)
end<-c(d$V2)
if(pn<0){
sign<-sign(start-end)
}else if(pn>0){
sign<-sign(end-start)
}else{
sign<-rep(1,length(start))
}
sign2<-c(sign,sign)
sign2<-(sign2+1)/2
startend<-c(start,end)
value<-c(rep(1,length(start)),rep(-1,length(end)))
value<-value*sign2
mat<-matrix(c(startend,value),ncol=2)
order<-order(mat[,1])
accum<-rep(1,length(startend))
accum[1]=mat[order,2][1]
for(i in 2:length(startend)){
accum[i]<-accum[i-1]+mat[order,2][i]
}
retmat<-matrix(c(mat[order,1],accum),ncol=2)
return(retmat)
}
データがテキストファイル "test.txt"に、1データ1行のタブ区切りで次のように入っているとする
4 6 2 5 7 9 1 8
Rでこれを読んで処理するとすると・・・
#ファイルを読む
> d<-read.table(file="test.txt")
#読んだファイルを見てみる
> d
V1 V2
1 4 6
2 2 5
3 7 9
4 1 8
#始点はV1のカラムなので、それを取り出す
> start<-c(d$V1)
> start
[1] 4 2 7 1
#終点はV2のカラムなので、それを取り出す
> end<-c(d$V2)
#始点と終点を同じベクトルに入れる
> startend<-c(start,end)
> startend
[1] 4 2 7 1 6 5 9 8
#始点と終点を併せた要素数と同じ長さで、始点には1が終点には-1が対応するような、ベクトルを作る
> value<-c(rep(1,length(start)),rep(-1,length(end)))
> value
[1] 1 1 1 1 -1 -1 -1 -1
#始点終点の位置を第一列に持ち、それに与えた1,-1の値を第2列に持つような行列を作る
> mat<-matrix(c(startend,value),ncol=2)
> mat
[,1] [,2]
[1,] 4 1
[2,] 2 1
[3,] 7 1
[4,] 1 1
[5,] 6 -1
[6,] 5 -1
[7,] 9 -1
[8,] 8 -1
#始点終点の位置でソートする
> mat[order(mat[,1]),]
[,1] [,2]
[1,] 1 1
[2,] 2 1
[3,] 4 1
[4,] 5 -1
[5,] 6 -1
[6,] 7 1
[7,] 8 -1
[8,] 9 -1
#始点終点の位置でソートしたときの第2列ベクトルを確認する
> mat[order(mat[,1]),2]
[1] 1 1 1 -1 -1 1 -1 -1
#インクリメント・デクリメント作業のために、三角行列を作る
> matb<-matrix(rep(1,length(startend)^2),ncol=length(startend))
> matb
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 1 1 1 1 1 1 1
[2,] 1 1 1 1 1 1 1 1
[3,] 1 1 1 1 1 1 1 1
[4,] 1 1 1 1 1 1 1 1
[5,] 1 1 1 1 1 1 1 1
[6,] 1 1 1 1 1 1 1 1
[7,] 1 1 1 1 1 1 1 1
[8,] 1 1 1 1 1 1 1 1
> matb[upper.tri(matb)]<-0
> matb
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 0 0 0 0 0 0 0
[2,] 1 1 0 0 0 0 0 0
[3,] 1 1 1 0 0 0 0 0
[4,] 1 1 1 1 0 0 0 0
[5,] 1 1 1 1 1 0 0 0
[6,] 1 1 1 1 1 1 0 0
[7,] 1 1 1 1 1 1 1 0
[8,] 1 1 1 1 1 1 1 1
#インクリメント・デクリメントの結果を行列の積として計算する
> matb %*% mat[order(mat[,1]),2]
[,1]
[1,] 1
[2,] 2
[3,] 3
[4,] 2
[5,] 1
[6,] 2
[7,] 1
[8,] 0