No.22282 距離行列からの特定データ抽出  【shimp】 2017/02/24(Fri) 15:51

Rを用いて得た距離行列から特定の条件を満足する組合せを抽出したいと考えています。

例えば,
(USA.dist <- dist(USArrests)^2)
で得られる距離行列から,値10,000を超える組合せのみを抽出したいと考えています。
抽出するためには,データフレームへの変換が必要だと考えて,
(USA.dist <- as.data.frame(as.matrix(USA.dist)))
としたうえで,
(subset(USA.dist, USA.dist > 10000))
としてみたのですが,NAで埋まった行名も失われた出力となってしまいます。

subsetの書き方がまずい様な気がするのですが,そもそもas.data.frame(as.matrix())といった使い方がいかにも力づくだと感じています。
どうかアドバイスを賜りたく何卒宜しくお願い致します。

No.22283 Re: 距離行列からの特定データ抽出  【青木繁伸】 2017/02/25(Sat) 09:48

「特定データの抽出」とは,どのようなことを意味するのでしょうか?
> (x <- c(a=2, b=4, c=1, d=6, e=7))
a b c d e
2 4 1 6 7

> (y <- dist(x)^2) # class(y) は "dist" 三角行列
a b c d
b 4
c 1 9
d 16 4 25
e 25 9 36 1

> (z <- as.matrix(y)) # class(z) は "matrix" 正方行列
a b c d e
a 0 4 1 16 25
b 4 0 9 4 9
c 1 9 0 25 36
d 16 4 25 0 1
e 25 9 36 1 0

> # ある値より大きい要素の添え字
> which(z > 20) # デフォルトでは,arr.ind=FALSE になっており,結果はベクトルでの index
[1] 5 14 15 18 21 23

> (index <- which(z > 20, arr.ind=TRUE)) # arr.ind= TRUE で,行列での index
row col
e 5 1
d 4 3
e 5 3
c 3 4
a 1 5
c 3 5

> # 実際のその要素
> z[index]
[1] 25 25 36 25 25 36 # ベクトルからの抽出

> # 行列のまま抽出しようという試みは挫折する(これでもいいということか?)
> z[index, , drop=FALSE]
a b c d e
e 25 9 36 1 0
d 16 4 25 0 1
e 25 9 36 1 0
c 1 9 0 25 36
a 0 4 1 16 25
c 1 9 0 25 36
a 0 4 1 16 25
c 1 9 0 25 36
c 1 9 0 25 36
d 16 4 25 0 1
e 25 9 36 1 0
e 25 9 36 1 0

> # ある値より大きい要素の添え字を行列名に変換
> matrix(colnames(z)[t(index)], byrow=TRUE, ncol=2)
[,1] [,2]
[1,] "e" "a"
[2,] "d" "c"
[3,] "e" "c"
[4,] "c" "d"
[5,] "a" "e"
[6,] "c" "e"

> # これではないのでしょうけど
> u <- z
> u[u < 20] <- 0
> u
a b c d e
a 0 0 0 0 25
b 0 0 0 0 0
c 0 0 0 25 36
d 0 0 25 0 0
e 25 0 36 0 0

> # こっちとか
> v <- z
> b <- apply(v, 1, function(a) any(a > 20))
> v[b, b]
a c d e
a 0 1 16 25
c 1 0 25 36
d 16 25 0 1
e 25 36 1 0

No.22284 Re: 距離行列からの特定データ抽出  【shimp】 2017/02/25(Sat) 15:20

有難う御座います。説明が不適切・不足していたことをお詫びします。

やりたかったことは,まさしく最後のケースです。
また最初の質問で" > 10000"としていたのは誤りで,やりたいことはご近所探しであったため不等号の向きが逆でした。重ねて申し訳ありません。

5,000件くらいの膨大なデータの中からご近所を取り出して,距離の数字を確認しながらデンドログラムを眺めてみたいと思ったのです。
par(mfrow = c(1, 2))

x <- c(a=1, b=2, c=5, d=8, e=11, f=14, g=17, h=20, i=23, j=26, k=29, l=32, m=35, n=38, o=41, p=42, q=43)
(y <- dist(x)^2)
plot(hclust(y),hang=-1)

v <- as.matrix(y)
b <- apply(v, 1, function(a) any(a < 3 & a > 0))
(w <- as.dist(v[b, b]))
plot(hclust(w),hang=-1)
週明けに実際のデータに当ててみるのが楽しみでなりません。
有難う御座いました。

● 「統計学関連なんでもあり」の過去ログ--- 048 の目次へジャンプ
● 「統計学関連なんでもあり」の目次へジャンプ
● 直前のページへ戻る