« 09.02 Maven2でwarファイルを作る | ココ | 09.14 シンプルなCSSテンプレート無料サイト(メモ) »

2011年9月 5日

Rで再現させようとして無駄に嵌った  このエントリーを含むはてなブックマーク 

どうも、最近全然プログラミング的なことを書いてないのでプログラム作ってないんじゃないかと思われそうなんですが、ええ、その通りです。いやしかし、妙に不可思議な現象に嵌ったのでちょっとメモ。

Rでデータフレームを作って集計をしようとしたときに、前に作ったデータだとうまく処理されて、次に作ったデータだとなぜだかうまく処理されない、という、まったくもって原因が分からないことに…。そもそもどうしてわかったかというと、小数であるはずのデータが処理後にとてつもなく大きな整数になってたからでして。実際のデータは使えないので、頑張ってミニマムコードを作ってみた。なんかこれだけでも結構無駄に時間使った気がする。


df<-data.frame(cbind(
    y=rep(letters[1:13],2),
    x=as.character(1:10),
    z=c(as.character(as.integer(runif(n=240,min=0,max=100))/1000),rep(NA,20))
))

これで、1列目にa~m(アルファベット1文字目から13文字目)の2回繰り返し、2列目に1~10の2.6回繰り返し、3列目に0~0.1のランダムな数値(一様分布のランダムな数)240個と20個のNAが詰まった260行のデータが出来上がる。

これを

> tapply(df$z, list(df$x, df$y),
    function(aa) as.numeric(max(as.numeric(as.vector(aa)))))

      a     b     c     d     e     f     g     h     i     j     k     l
1  0.069 0.071 0.042    NA 0.076 0.095    NA 0.054 0.070 0.095 0.060 0.081
10 0.020 0.086    NA 0.095 0.056 0.094 0.061 0.087 0.071 0.064 0.079 0.050
2  0.040 0.096 0.038 0.062    NA 0.086 0.064    NA 0.087 0.046 0.080 0.024
3  0.087 0.090 0.098 0.047 0.076    NA 0.046 0.017    NA 0.082 0.044 0.083
4  0.070 0.066 0.048 0.090 0.088 0.075    NA 0.063 0.084    NA 0.047 0.069
5  0.072 0.071 0.090 0.076 0.049 0.071 0.085    NA 0.087 0.053    NA 0.068
6  0.098 0.046 0.018 0.081 0.057 0.078 0.053 0.087    NA 0.025 0.076    NA
7  0.025 0.033 0.070 0.008 0.086 0.072 0.048 0.015 0.084    NA 0.016 0.099
8     NA 0.081 0.032 0.075 0.042 0.083 0.082 0.057 0.016 0.038    NA 0.071
9  0.082    NA 0.070 0.072 0.020 0.024 0.033 0.061 0.068 0.028 0.063    NA

      m
1  0.076
10    NA
2  0.069
3  0.094
4  0.095
5  0.068
6  0.055
7     NA
8  0.061
9  0.086

とすると、たとえばこういう風にNAが混ざる。これはNAをちゃんと処理してないから当然なわけで。だから、NAを処理しようとして、こうすると、

> tapply(df$z, list(df$x, df$y),
    function(aa) max(as.numeric(as.vector(ifelse(is.na(aa), 0, aa)))))

   a  b  c  d  e  f  g  h  i  j  k  l  m
1  63 65 38 57 69 84  8 49 64 84 54 74 69
10 19 79 70 84 51 83 55 80 65 58 72 46 21
2  36 85 34 56 55 79 58 35 80 42 73 23 63
3  80 82 86 43 69 49 42 17 25 75 40 76 83
4  64 60 44 82 81 68 12 57 77 72 43 63 84
5  66 65 82 69 45 65 78 29 80 48 20 62 62
6  86 42 18 74 52 71 48 80 22 24 69 43 50
7  24 31 64  9 79 66 44 15 77 87 16 87  3
8  29 74 30 68 38 76 75 52 16 34 11 65 55
9  75 44 64 66 19 23 31 55 62 26 57 65 79

不思議なことに、全然さっきと違う数字が!!!! データフレームになっているから、それぞれのデータのインデックス番号っぽいなぁということは気が付いたけど、これ、どうやって小数で出すねん。というのが問題。


> tapply(df$z, list(df$x, df$y),
    function(aa) max(as.numeric(ifelse(is.na(aa), 0, as.vector(aa)))))

      a     b     c     d     e     f     g     h     i     j     k     l
1  0.069 0.071 0.042 0.063 0.076 0.095 0.007 0.054 0.070 0.095 0.060 0.081
10 0.020 0.086 0.077 0.095 0.056 0.094 0.061 0.087 0.071 0.064 0.079 0.050
2  0.040 0.096 0.038 0.062 0.061 0.086 0.064 0.039 0.087 0.046 0.080 0.024
3  0.087 0.090 0.098 0.047 0.076 0.054 0.046 0.017 0.027 0.082 0.044 0.083
4  0.070 0.066 0.048 0.090 0.088 0.075 0.012 0.063 0.084 0.079 0.047 0.069
5  0.072 0.071 0.090 0.076 0.049 0.071 0.085 0.031 0.087 0.053 0.021 0.068
6  0.098 0.046 0.018 0.081 0.057 0.078 0.053 0.087 0.023 0.025 0.076 0.047
7  0.025 0.033 0.070 0.008 0.086 0.072 0.048 0.015 0.084 0.099 0.016 0.099
8  0.031 0.081 0.032 0.075 0.042 0.083 0.082 0.057 0.016 0.038 0.011 0.071
9  0.082 0.048 0.070 0.072 0.020 0.024 0.033 0.061 0.068 0.028 0.063 0.071

      m
1  0.076
10 0.022
2  0.069
3  0.094
4  0.095
5  0.068
6  0.055
7  0.002
8  0.061
9  0.086

ifelse()をas.vector()の内側にするか外側にするかで返ってくるのが違うのがどうも解せない。

By ただ at 22:00 カテゴリー ; プログラミングとか

« 09.02 Maven2でwarファイルを作る | 09月の記事 | 09.14 シンプルなCSSテンプレート無料サイト(メモ) »




トラックバック

このエントリーのトラックバックURL:
http://pinmarch.sakura.ne.jp/mt/mt-tb.cgi/1763