No.12811 Rによる解析法  【ボラーノ広場】 2010/06/10(Thu) 21:26

Rの使い手の皆様に質問させていただきます。
エリアデータがあります。位置(x,y座標)およびその地点の数値(生産量や収穫量)
対象エリアの大きさは1000×1000とします。対象エリアを5×5や10×10に区切って,各
エリア中の数値のそれぞれの合計を求めたいと思います。Rのcut関数やmatrix()を使い
データフレームと連携させながら解析するものと想像します。
せひご教示いただきたくお願い致します。

No.12812 Re: Rによる解析法  【青木繁伸】 2010/06/10(Thu) 23:11

このような関数は,色々うまい方法を探すのもおもしろいものの,探す時間よりは単純なプログラムを自分で書いた方が,トータルの時間は短くなる傾向があるでしょう。
条件が付いているので(例えば,今の場合,正方行列であるとか,まとめる行数・列数は全体の行数・列数の約数であるとか)一般的なプログラムを書く必要はないので面倒なことが省ける。
で,以下のようなプログラム。例題による検証も。
第二引数は,何行何列ごとにまとめるかという数。
n <- 12
(a <- matrix(1:n^2, n))
Aggregate <- function(a, m)
{
n <- nrow(a)
if (n != ncol(a) || n %% m != 0) stop("変なデータ")
k <- n %/% m - 1
res <- matrix(0, k+1, k+1)
for (i in 0:k) for (j in 0:k) {
i1 <- (i*m+1):((i+1)*m)
j1 <- (j*m+1):((j+1)*m)
res[i+1, j+1] <- sum(a[i1, j1])
}
return(res)
}

Aggregate(a, 2)
Aggregate(a, 3)
Aggregate(a, 4)
Aggregate(a, 6)
結果は,
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,] 1 13 25 37 49 61 73 85 97 109 121 133
[2,] 2 14 26 38 50 62 74 86 98 110 122 134
[3,] 3 15 27 39 51 63 75 87 99 111 123 135
[4,] 4 16 28 40 52 64 76 88 100 112 124 136
[5,] 5 17 29 41 53 65 77 89 101 113 125 137
[6,] 6 18 30 42 54 66 78 90 102 114 126 138
[7,] 7 19 31 43 55 67 79 91 103 115 127 139
[8,] 8 20 32 44 56 68 80 92 104 116 128 140
[9,] 9 21 33 45 57 69 81 93 105 117 129 141
[10,] 10 22 34 46 58 70 82 94 106 118 130 142
[11,] 11 23 35 47 59 71 83 95 107 119 131 143
[12,] 12 24 36 48 60 72 84 96 108 120 132 144
> Aggregate(a, 2)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 30 126 222 318 414 510
[2,] 38 134 230 326 422 518
[3,] 46 142 238 334 430 526
[4,] 54 150 246 342 438 534
[5,] 62 158 254 350 446 542
[6,] 70 166 262 358 454 550
> Aggregate(a, 3)
[,1] [,2] [,3] [,4]
[1,] 126 450 774 1098
[2,] 153 477 801 1125
[3,] 180 504 828 1152
[4,] 207 531 855 1179
> Aggregate(a, 4)
[,1] [,2] [,3]
[1,] 328 1096 1864
[2,] 392 1160 1928
[3,] 456 1224 1992
> Aggregate(a, 6)
[,1] [,2]
[1,] 1206 3798
[2,] 1422 4014
こんなところでいかがでしょう。正方行列ではないとか,何行何列ごとにまとめるけど,最後の行列はそれよりも少ない行列を含むというように拡張するのは必要があればそんなに面倒なことでもない。

No.12815 Re: Rによる解析法  【ポラーノ広場】 2010/06/11(Fri) 08:44

青木先生ご回答ありがとうございました。

行列の操作は大変参考になりました。
さて,位置データ(x,y座標)は0〜1000までの実数で,2000個所(点)あります。
まず全対象エリアを例えば10×10の100区画に区切って,各区画内に入る位置データに
対応した数値(生産量や収穫量)の集計(合計や平均)方法もぜひご教示いただけれ
ば幸いです。どうぞよろしくお願いいたします。

No.12817 Re: Rによる解析法  【青木繁伸】 2010/06/11(Fri) 13:08

小数部を丸めた座標値が同じデータが2つ以上あることはないということなら,そのデータを 1001 × 1001 の配列に収めれば,先のプログラムが応用できますが,重複するデータがある場合にも対応できるよう,以下のようにした方が分かりやすい。
aggregate 関数を使うだけで求まります。関数にするとちょっとだけ便利?
set.seed(123)
x <- sample(0:1000, 2000, replace=TRUE)
y <- sample(0:1000, 2000, replace=TRUE)
z <- round(rnorm(2000, mean=100, sd=10), 1)

Aggregate2 <- function(x, y, z, delta, FUN=mean)
{
x1 <- x %/% delta
y1 <- y %/% delta
aggregate(z, by=list(x1, y1), FUN=FUN)
}
Aggregate2(x, y, z, 100, length)
Aggregate2(x, y, z, 100, sum)
Aggregate2(x, y, z, 100, mean)
Aggregate2(x, y, z, 100, sd)

No.12818 Re: Rによる解析法  【ポラーノ広場】 2010/06/11(Fri) 16:48

青木先生 
2度にわたってご回答をいただきありがとうございました。

先生の定義された関数AggregateおよびAggregate2はまさに目から鱗が落ちました。
また,この中のaggregate()も初めて使いました。便利です。
x,yをcut関数で範囲を分けてから,zをaggregate()で求めて,その後にMatrixで行列に入れると,私が最初に考えていた手順(ストーリー)通りに集計が終わりました。
大変参考になりました。感謝,感謝です。

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