【R言語】統計解析フリーソフトR 第6章【GNU R】 [無断転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
Reduce何て便利な関数が標準装備されていたんだな。 ?Reduce Reduce("+", c(1,2,3,4)) Reduce("+", c(1,2,3,4), accumulate = TRUE) cumsum(c(1,2,3,4)) factorial(4) Reduce('*',c(1,2,3,4)) Reduce("*", c(1,2,3,4), accumulate = TRUE) cumprod(c(1,2,3,4)) Reduce("*", c(1,2,3,4), accumulate = TRUE,right=TRUE) rev(Reduce("*", c(1,2,3,4), accumulate = TRUE,right=TRUE)) cumprod(rev(c(1,2,3,4))) 96歳の女性をお看取り。肺も心臓も腎臓も機能低下していたが、年齢を考慮して死因は老衰にした。ふと96歳の平均余命はどれくらいかが気になって平成27年簡易生命表(女)を調べてみた。 http://www.mhlw.go.jp/toukei/saikin/hw/life/life15/dl/life15-07.pdf こういう表をみると自分で計算してみたくなる。諸関数の定義が厚労省の参考資料で解説されているのでRが使えれば計算は容易(ド底辺特殊シリツ医大卒には無理) ## 10万人あたりの死亡数から平均余命を算出 f=c(178,31,20,12,8,8,8,8,7,7,7,7,7,7,8,10,12,13,15,16,17,18,20,21,23,24,25,27,29, 30,31,32,34,37,39,41,43,46,50,56,62,68,73,79,86,94,103,113,123,134,145,159,174, 188,202,215,226,237,251,269,292,319,346,372,401,435,472,510,553,602,661,727,799, 870,952,1053,1180,1331,1503,1698,1914,2153,2419,2708,3011,3320,3628,3926,4227, 4513,4743,4896,4937,4867,4678,4385,4004,3557,3069,2567,2077,1623,1220,880,608, 960) m=c(201,32,23,15,11,10,10,10,9,8,7,7,8,11,14,17,22,27,33,39,44,47,50,52,53,54,54, 54,54,56,58,59,62,65,70,73,76,79,85,93,103,113,122,131,145,159,176,195,215,237, 259,285,311,341,374,412,451,490,528,572,625,692,767,842,919,1002,1084,1166,1254, 1349,1452,1562,1668,1764,1875,2015,2182,2375,2586,2806,3038,3280,3506,3709,3887, 4024,4089,4088,4037,3944,3803,3555,3243,2887,2507,2122,1749,1403,1095,829,609, 434,298,198,127,180) LE <-function(ndx,Y,N0=10^5){ n=length(ndx) lx=numeric(n) lx[1]=N0 for(i in 1:(n-1)) lx[i+1] <- lx[i] - ndx[i] nqx=ndx/lx nLx=numeric(n) for(i in 1:n) nLx[i] <- mean(c(lx[i],lx[i+1])) nLx[n]=0 Tx=rev(cumsum(rev(nLx))) le=Tx/lx return(round(le[Y+1],1)) } >>356 実行すると > LE(f,96) [1] 3.4 96歳女性の平均余命は3年以上あるらしい。 死因は多臓器不全にする方が正しかったのだろうか? > LE(m,100) [1] 2.1 参考資料1 生命表諸関数の定義 http://www.mhlw.go.jp/toukei/saikin/hw/life/life15/dl/life15-08.pdf に寿命中位数というのが定義されている。 半減期にあたる寿命中位数も計算してみた。グラフであたりをつけて内挿してもとめた。 手計算は面倒なのでRで線形回帰 x=c(89,90) y=c(nLx[89+1],nLx[90+1]) # y = a + b*x coef=lm(y~x)$coef round((50000-coef[1])/coef[2],1) # 寿命中位数 > round((50000-coef[1])/coef[2],1) # 寿命中位数 89.3 参考資料中の解説 我が国は、「平均寿命<寿命中位数」となっている。 が確認できた。 待機時間の多い職場だと、ふとした疑問をネットで調べて自分で勉強できて( ・∀・)イイ!! ド底辺特殊シリツ医大卒のネット検索後の学習結果は>119を参照。 どうでもいいけど、平成27年は完全生命表の年なのに、 なぜわざわざ簡易生命表を使うの? >>111 5〜6年ほど前にやってたな。 生命表と幾何ブラウン運動に基づく株価のモンテカルロシミュレーションで、今の貯蓄で死ぬまでにお金を使い切る確率を計算するの。 >>115 第22回生命表(完全生命表) ttp://www.mhlw.go.jp/toukei/saikin/hw/life/22th/index.html なお、最新版の平成28年の簡易生命表はこちら ttp://www.mhlw.go.jp/toukei/saikin/hw/life/life16/index.html >>116 ## 第22回生命表(完全生命表) #http://www.mhlw.go.jp/toukei/saikin/hw/life/22th/index.html F=c(178,32,20,12,8,8,8,8,7,7,7,7,7,7,8,10,12,13,15,16,17,19,20,22,23,24,25,27,28,30,31,32,34,36,39,41,42,45,50,56, 62,68,73,79,85,94,104,114,124,134,145,159,174,189,202,215,226,237,250,268,291,318,346,372,399,433,471,511,554,603,662,729,802,874,954,1053,1180,1332,1505,1699,1909,2143,2409,2701,3004,3310,3622,3938,4253,4531,4757,4918,5025, 5024,4876,4598,4132,3594,3025,2464,1941,1477,1085,769,525,345,217,132,76,42,22,11,5,2,1,0) M=c(202,34,24,16,11,10,10,10,9,8,7,7,8,11,13,17,21,26,32,39,45,49,51,53,55,55,54,54,54,56,57,59,61,65,69,73,75,78, 84,93,103,113,122,131,144,159,176,195,215,236,257,283,310,340,373,411,450,488,525,568,620,688,764,839,910,994, 1081,1166,1256,1349,1450,1561,1675,1776,1885,2021,2185,2377,2594,2819,3046,3279,3504,3714,3900,4043,4116,4127, 4080,3973,3810,3580,3302,2967,2567,2123,1718,1352,1034,768,554,387,262,171,108,66,39,22,12,6,3,2,1) LE <-function(ndx,Y,N0=10^5){ n=length(ndx) lx=numeric(n) lx[1]=N0 for(i in 1:(n-1)) lx[i+1] <- lx[i] - ndx[i] nqx=ndx/lx nLx=numeric(n) for(i in 1:n) nLx[i] <- mean(c(lx[i],lx[i+1])) nLx[n]=0 Tx=rev(cumsum(rev(nLx))) le=Tx/lx return(round(le[Y+1],2)) } >>117 最新版の平成28年の簡易生命表はこちら f=c(198,29,19,12,9,7,7,6,5,6,6,7,7,7,8,9,11,12,13,14,16,19,22,24,25,25,25,25,25,26,28,29,31,34,37,41,45,48,50,54,59,66,72,78,84,92,101,112,123,136,149,162,175,186,196,207,220,237,256,275,294,313,334,360, 389,423,463,504,547,595,649,707,776,855,940,1043,1164,1308,1479,1667,1874,2102,2363,2651,2955,3265,3567,3874,4186,4484,4731,4908,5039,5067,4936,4635,4209,3697,3139,2574,2037,1554,1141,805,545,846) m=c(194,31,21,14,10,9,9,8,7,7,7,7,8,10,13,17,21,26,31,38,44,48,50,51,51,51,53,53,54,56,57,58,60,63,66,70,74,79,83,89,97,106,116,127,140,155,171,190,211,233,255,278,302,328,359,395,434,478,525,572,622, 678,741,813,890,973,1062,1148,1233,1323,1419,1522,1633,1752,1874,2014,2176,2357,2553,2762,2985,3221,3459,3680,3875,4031,4123,4156,4123,4023,3874,3643,3349,3006,2629,2235,1843,1470,1131,837,593,401,258,157,89,90) LE <-function(ndx,Y,N0=10^5){ n=length(ndx) lx=numeric(n) lx[1]=N0 for(i in 1:(n-1)) lx[i+1] <- lx[i] - ndx[i] nqx=ndx/lx nLx=numeric(n) for(i in 1:n) nLx[i] <- mean(c(lx[i],lx[i+1])) nLx[n]=0 Tx=rev(cumsum(rev(nLx))) le=Tx/lx return(round(le[Y+1],1)) } LE(f,96) LE(m,100) > LE(f,96) # 96歳女性の平均余命 [1] 3.3 > LE(m,100) #100歳男性の平均余命 [1] 1.9 微妙に結果が違うな。 ド底辺特殊シリツ医大に http://egg.2ch.net/test/read.cgi/hosp/1506113587/142 のようなスカトロ嗜好の医者がいるかを 1学年100人として無作為の順序で調査していき該当者が1人発見されたら調査終了とするという方法で調査する。 1例目が該当者であった。 この学年のスカトロ嗜好数の期待値を求めよ。 lottery <- function(.N,.r,k=10^4){ f <-function(S,N=.N){ y=c(rep(1,S),rep(0,N-S)) Y=sample(y) return(Y) } g <- function(y){ n=length(y) for(i in 1:n){ if(!y[i]) i=i+1 else break } return(i) } xx=0:.N SS=NULL for(i in 1:k){ M=t(sapply(xx,f)) for(j in 1:.N){ if(g(M[j,])==.r) SS=c(SS,j-1) } } print(quantile(SS,c(.025,.05,.50,.95,.975))) c(mean=mean(SS)) } lottery(100,1) > lottery(100,1) 2.5% 5% 50% 95% 97.5% 16 22 70 97 98 mean 66.31167 lottery <- function(.N,.r,k=10^3){ f <-function(S,N=.N){ y=c(rep(1,S),rep(0,N-S)) Y=sample(y) return(Y) } g <- function(y){ n=length(y) for(i in 1:n){ if(!y[i]) i=i+1 else break } return(i) } xx=0:.N SS=NULL for(i in 1:k){ M=t(sapply(xx,f)) for(j in 1:(.N+1)){ if(g(M[j,])==.r) SS=c(SS,j-1) } } print(quantile(SS,c(.025,.05,.50,.95,.975))) c(mean=mean(SS)) } lottery(100,1) Linux版のRでもWindows版みたいに「入力:青字、出力:赤字」みたいなインターフェースにする設定ってある? >>125 coloroutパッケージ入れて、色を割り当てるとできるかも。 アーカイブに入っちゃっているけど、使える。 setOutputColors256()のヘルプを参照。 順番を表示させる、*1st,*2nd *3rd > n=21 > paste(n,ifelse(0<n%%10 && n%%10<4,c('st','nd','rd')[which(n%%10==1:3)],'th'),sep='') [1] "21st" >>128 それだと、11が11stになっておかしいだろ > library(toOrdinal) > toOrdinal(21) [1] "21st" > sapply(1:20, toOrdinal) [1] "1st" "2nd" "3rd" "4th" "5th" "6th" "7th" "8th" "9th" "10th" [11] "11th" "12th" "13th" "14th" "15th" "16th" "17th" "18th" "19th" "20th" >>128 なんでそこで && を使うかなあ。&& の意味わかってる? ifelse には & を使うことになるのが普通だし、そうでなければ if 〜 else のほうがよい。 >>129 ご指摘とパッケージの御教示ありがとうございました。 >>131 ?&で勉強になりました。 御教示ありがとうございました。 >>130 toOrdinal のコードをみたら 11,12,13は別扱いしてあった。 if (tmp %in% c("11", "12", "13")) tmp.suffix <- "th" legendの中で使うべくone-linerにしたかったのだけど、ここでの指摘に従ってデバッグしたら paste(n,ifelse(as.character(n%%100)%in%c('11','12','13'),'th',ifelse(0<n%%10 & n%%10<4,c('st','nd','rd')[which(n%%10==1:3)],'th')),sep='') こんなに長くなってしまった。 > f<-function(n)paste(n,ifelse(as.character(n%%100)%in%c('11','12','13'),'th', + ifelse(0<n%%10 & n%%10<4,c('st','nd','rd')[which(n%%10==1:3)],'th')),sep='') > prod(sapply(0:10000,f) == sapply(0:10000,toOrdinal::toOrdinal)) [1] 1 一応、パッケージtoOrdinalと0〜1万で合致を確認。 いろいろとご助言ありがとうございました。 <(_ _)>ペコリ パチンコのスレにこういう記載があった。 >バカは何故かパチンコで勝てると思い込んでいる >バカは本来なら勝てるのに遠隔や不正で負けていると思い込んでいる >バカは10分の1で10円が当たるクジより1万分の1で8000円が当たるクジの方が儲かると思ってる >算数すらできないバカが必死に守って支えてきたのがパチンコ業界 これを読んでこんな問題を考えてみた。 宝くじAは1000本中100本が当たりで当たりは 100万円の賞金、 宝くじBは1000本中 10本が当たりで当たりは1000万円の賞金、 どちらも売り出し価格は同じなので計100本買うことにする。 Aを何本買うときに賞金の期待値が最大になるか、シミュレーションしてみよ。 シミュレーションすると Na=1000 ; Nb=1000 # くじの本数 pa=0.1 ; pb=0.01 # 当たる確率 Wa=100 ; Wb=1000 # 賞金 n=100 # 買う総本数 aa=0:n # 宝くじAを買う候補 A0=c(rep(1,Na*pa),rep(0,Na-Na*pa)) # 宝くじA 1:当たり 0:はずれ B0=c(rep(1,Nb*pb),rep(0,Nb-Nb*pb)) # 宝くじB Get <- function(a){ #Aをa本買ったときのAの当たりとBのあたりでの賞金合計 sum(sample(A0,a))*Wa + sum(sample(B0,n-a))*Wb } k=10^3 #繰り返し回数 MAX=replicate(k,which.max(sapply(aa,Get))-1) # 賞金合計が最大になるAの購入数の配列 hist(MAX) 期待値がA,BでかわらないからMAXの分布は一様分布になると思ったのだが、 こんな分布になってしまって自分でも混乱している。 http://i.imgur.com/Yo55mvc.png お知恵を拝借したい。 自分なら、こんな感じ > a <- function(i){sum(rbinom(i, 1, 0.1) * 100) + sum(rbinom(100-i, 1, 0.01) * 1000)} > b <- function(){which.max(sapply(1:100, a))} 1000回のシミュレーションだと > res <- replicate(1000, b()) > hist(res) 同じ結果だよ A, Bを少なくとも1本含む100本じゃなかったので、 > b <- function(){which.max(sapply(1:100, a))} は > b <- function(){which.max(sapply(0:100, a))} だな。すまん > a <- function(i){sum(rbinom(i, 1, 0.1) * 100) + sum(rbinom(100-i, 1, 0.01) * 1000)} > b <- function(){which.max(sapply(0:100, a))} > res <- replicate(1000, b()) > hist(res,breaks = 20) 結果は同じ >139-142 簡潔なコードありがとうございます。 AもBも賞金の期待値がどちらも10万なので Aを何本買おうが合計の期待値は同じかなと思いつつ、sample関数を使ってシミュレーションしたのだけれど 一様分布にはならないのでシミュレーションの間違い、 もしくは自分が理解していないsample関数の特性を検出しただけなのか、と思っておりました。 rbinomでのシミュレーション結果とヒストグラムが一致して、一様分布になるという思い込みが間違いだと確信できました。 勉強になりました。ありがとうございました。 >>142 大したことではないけど 0から始まるので本数とindexを補正して b <- function(){which.max(sapply(0:100, a))-1} の方が正確だと思います。 宝くじをA,B併せて100本買ったときの賞金の期待値は Award <- function(i){ #i:Aを買った本数 sum(dbinom(0:i,i,0.1)*(0:i)*100)+sum(dbinom(0:(100-i),100-i,0.01)*(0:(100-i))*1000) } sapply(0:100,Award) > sapply(0:100,Award) [1] 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 .... [86] 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 と買い方に無関係にも思えるんだなぁ。 >>145 >合計の期待値の標準偏差はAの本数が増えると減る ことを検証してみた。 a <- function(i) sum(rbinom(i, 1, 0.1) * 100) + sum(rbinom(100-i, 1, 0.01) * 1000) plot(0:100,sapply(0:100,function(x) sd(replicate(10^3,a(x))))) http://i.imgur.com/oPFtMXe.png 別の話題提供。 ゴルゴ13は100発100中 ゴルゴ14は10発10中 ゴルゴ15は1発1中 とする。 各々10000発撃ったとき各ゴルゴの命中数の期待値はいくらか? どうでもいいんだが、 which.max()は、同値の最大が複数あったとき、最初のインデックスを戻すので、 2番目以降の最大が無視されていることについて、その取り扱いを考慮した方が良いと思うぞ。 > which.max(c(0,1,0,0,0,0,0,0,1)) [1] 2 >>149 ご指摘ありがとうございます。 最大値を与えるAの購入数が複数ある場合を考えてスクリプトを改変してみました。 a <- function(i){sum(rbinom(i, 1, 0.1) * 100) + sum(rbinom(100-i, 1, 0.01) * 1000)} which.max2 <- function(x){which(x==max(x))-1} b <- function(){ b1=NULL b1=c(b1,which.max2(sapply(0:100, a))) return(b1) } b2=NULL for(j in 1:1000){ b2=c(b2,b()) } hist(b2,breaks=20) length(b2) とすると1000を超えているから同値の最大が複数あったことがわかりました。 ありがとうございました。 このスレは勉強になるなぁ。 どうでもいいことだけど、 hist(b2,breaks=20,col=sample(colors(),2)) とすると毎回配色の変わるツートンカラーのヒストグラムがでて面白い。 >>126 125です。レス遅くなったけど、やりたいことができました。ありがとう。 array(1:48, dim=c(6, 4, 2)) を,3行2列おきに平均して ,,1 [,1] [,2] [1,] 5 17 [2,] 8 20 ,,2 [,1] [,2] [1,] 29 41 [2,] 32 44 としたいんですが,効率的な方法はないでしょうか。 実際のデータは,10000x10000x400なんです。 >>154 >3行2列 さっぱりわからん。 例えば、結果の[1,1,1]の5は、どれとどれの平均? >>155 6行4列の左上の6つ1,2,3,7,8,9の平均5だと思う。 >>154 効率的かどうかはわからんが、やってみた (d=array(1:48, dim=c(6, 4, 2))) a=3 b=2 l=6 m=4 n=2 re=NULL for(k in 1:n){ for(j in 1:(m/b)){ for(i in 1:(l/a)){ re=append(re,mean(d[1:3+3*(i-1),1:2+2*(j-1),k])) } } } array(re,dim=c(m/b,l/a,n)) >>155 >>154 です。 説明が悪くてすみません。 >>156 の通りです。 >>157 ありがとうございます。 手元にデータがないので明日試してみます。 なるほど、じゃあその5,8,17,20はこういうことか。 > a <- array(1:48, dim=c(6, 4, 2)) > b <- expand.grid(1:(dim(a)[1] %/% 3), 1:(dim(a)[2] %/% 2)) > f <- function(i, j, k=1){mean(a[(3*i-2):(3*i),(2*j-1):(2*j),k])} > mapply(f, b[,1], b[,2]) [1] 5 8 17 20 あぁ、すでに >>157 が回答を書いていたorz > d=array(1:48, dim=c(6, 4, 2)) > a=3 > b=2 > l=6 > m=4 > n=2 > re=NULL > for(k in 1:n){ + for(j in 1:(m/b)){ + for(i in 1:(l/a)){ + re=append(re,mean(d[1:a+a*(i-1),1:b+b*(j-1),k])) + } + } + } > array(re,dim=c(m/b,l/a,n)) , , 1 [,1] [,2] [1,] 5 17 [2,] 8 20 , , 2 [,1] [,2] [1,] 29 41 [2,] 32 44 データは10000x10000x400なら l=10000 m=10000 n=400 でよくね? 最初の1行で > d=array(1:(10000*10000*400)) Error: cannot allocate vector of size 298.0 Gb エラーがでたw 正しいエラーwはこっち > d=array(1:(10000*10000*400),dim=c(6, 4, 2)) Error: cannot allocate vector of size 298.0 Gb そもそも、10000x10000x400だと10000行は3行にならないな。最終行を無視して9999行にするのかな? >160を参考に>157のforだらけのスパゲティー・ソースを(ちょっと一般化して)改変しました。 (変数名の重複を避けるため>160の変数名は変更してあります。) > a=3 > b=2 > c=1 > > l=6 > m=4 > n=2 > > A <- array(1:48, dim=c(l,m,n)) > B <- expand.grid(1:(l %/% a), 1:(m %/% b),1:(n %/% c)) > f <- function(i, j, k){mean(A[(a*(i-1)+1):(a*i),(b*(j-1)+1):(b*j),(c*(k-1)+1):(c*k)])} > re=mapply(f, B[,1], B[,2],B[,3]) > array(re,dim=c(m%/%b,l%/%a,n%/%c)) , , 1 [,1] [,2] [1,] 5 17 [2,] 8 20 , , 2 [,1] [,2] [1,] 29 41 [2,] 32 44 > 上級者のコードを読むのは勉強になります。(深謝) 先輩方,>>154 です。 巨細にわたってご教示・ご議論いただきありがとうございました。 >>166 のコードを参考にして,無事処理することができました。 実行速度も申し分なく,効率的に作業が進められそうです。 今回は私には目から鱗な解法で,勉強になりました。 質問して良かったと思っています。。本当にありがとうございました。 10,000行の扱いですが,3行ごとに処理して1行無視してもよいし, 4から7行程度で処理してもよく,フレキシブルです。 今回は4行にして余りなしにしました。 処理速度を比べてみた。 fs<-function(){ #スパゲッティ・ソース d=array(1:(l*m*n),dim=c(l,m,n)) re=NULL for(k in 1:(n/c)){ for(j in 1:(m/b)){ for(i in 1:(l/a)){ re=append(re,mean(d[1:a+a*(i-1),1:b+b*(j-1),1:c+c*(k-1)])) }}} array(re,dim=c(m/b,l/a,n)) } fe <- function(){ # Expertソース A <- array(1:(l*m*n), dim=c(l,m,n)) B <- expand.grid(1:(l %/% a), 1:(m %/% b),1:(n %/% c)) f <- function(i, j, k){mean(A[(a*(i-1)+1):(a*i),(b*(j-1)+1):(b*j),(c*(k-1)+1):(c*k)])} re=mapply(f, B[,1], B[,2],B[,3]) array(re,dim=c(m%/%b,l%/%a,n%/%c)) } a=4 b=2 c=1 l=400 m=200 n=2 > system.time(fs()) user system elapsed 2.17 0.00 2.18 > system.time(fe()) user system elapsed 1.14 0.00 1.14 >160氏のスキルに改めて感服。 # 既約剰余類群 (Z/nZ)* kjrg <- function(n){ nn=0:(n-1) f=function(x,y) (x*y)%%n names(nn)=paste0('n',nn) z=outer(nn,nn,f) idx=which(gmp::gcd(1:(n-1),n)==1)+1 return(z[idx,idx]) } kjrg(10) kjrg(15) kjrg(24) > kjrg(24) n1 n5 n7 n11 n13 n17 n19 n23 n1 1 5 7 11 13 17 19 23 n5 5 1 11 7 17 13 23 19 n7 7 11 1 5 19 23 13 17 n11 11 7 5 1 23 19 17 13 n13 13 17 19 23 1 5 7 11 n17 17 13 23 19 5 1 11 7 n19 19 23 13 17 7 11 1 5 n23 23 19 17 13 11 7 5 1 # 既約剰余類群での加減乗除 n=24 n_star=which(gmp::gcd(1:(n-1),n)==1) ; n_star tasu <- function(x,y) (x+y)%%n hiku <- function(x,y) (x-y)%%n # row - col kake <- function(x,y) (x*y)%%n g=function(x) n_star[which(x==1)] .M=outer(n_star,n_star,kake) G=apply(.M,2,g) gyaku <- function(x) n_star[which(G==(x%%n))] waru <- function(x,y) (x*gyaku(y))%%n # row ÷ col xx=yy=c(0,n_star) names(xx)=paste0('x',c(0,n_star)) names(yy)=paste0('y',c(0,n_star)) outer(xx,yy,tasu) # x + y outer(xx,yy,hiku) # x - y outer(xx,yy,kake) # x * y X=Y=n_star #outer(X,Y,waru) # WRONG!! a=expand.grid(X,Y) b=matrix(mapply(waru,a[,1],a[,2]),length(X)) rownames(b)=paste0('x',n_star) colnames(b)=paste0('y',n_star) b # x / y 名前も一致してidenticalなんだな。 > x=1:10 > y=1:10 > identical(x,y) [1] TRUE > names(x)=LETTERS[1:10] > identical(x,y) [1] FALSE > names(y)=LETTERS[1:10] > identical(x,y) [1] TRUE > names(y)=letters[1:10] > identical(x,y) [1] FALSE allの方は内容の全体が一致していれば順番は入れ替わってもTRUEなんだな。 > x=1:10 > y=1:10 > all(x,y) [1] TRUE > names(x)=LETTERS[1:10] > all(x,y) [1] TRUE > names(y)=letters[1:10] > all(x,y) [1] TRUE > all(x,sample(y)) [1] TRUE beki <- function(x,n,p){ # x^n%%p if(n==0) return(1) if(n==1) return(x%%p) re=numeric(n) re[1]=x for(i in 1:(n-1)) re[i+1] = (x*re[i])%%p return(re[n]) } p=1009 # フェルマーの小定理 xx=0:(p-1) n=p-1 y=sapply(xx,function(x)beki(x,n,p)) summary(y) 90歳女性のお看取り >120のコードから女性の平均余命をグラフにしてみた Age=85:105 (Life_Expectancy=sapply(Age,function(x) LE(f,x))) plot(Age,Life_Expectancy,pch=19,col=sample(colors())) abline(h=5,col='gray',lty=2) http://i.imgur.com/38x50fw.png 平均余命が5年を切るのは92歳なので、老衰にせずに 主治医指定の病名で診断書を作成。 カルテ記載のしっかりした患者の診療は負担なくこなせて(・∀・)イイ!! outerって使えない場面があるよね? 剰余系での加減乗除での実際 > n=5 # prime number > nn=1:(n-1) > tasu <- function(x,y) (x+y)%%n > hiku <- function(x,y) (x-y)%%n # row - col > kake <- function(x,y) (x*y)%%n > g=function(x) nn[which(x==1)] > .M=outer(nn,nn,kake) > G=apply(.M,2,g) > gyaku <- function(x) nn[which(G==(x%%n))] > waru <- function(x,y) (x*gyaku(y))%%n # row / col > waru(3,2) [1] 4 > xx=yy=c(0,nn) > names(xx)=paste0('x',c(0,nn)) > names(yy)=paste0('y',c(0,nn)) > outer(xx,yy,tasu) # x + y y0 y1 y2 y3 y4 x0 0 1 2 3 4 x1 1 2 3 4 0 x2 2 3 4 0 1 x3 3 4 0 1 2 x4 4 0 1 2 3 > outer(xx,yy,hiku) # x - y y0 y1 y2 y3 y4 x0 0 4 3 2 1 x1 1 0 4 3 2 x2 2 1 0 4 3 x3 3 2 1 0 4 x4 4 3 2 1 0 > outer(xx,yy,kake) # x * y y0 y1 y2 y3 y4 x0 0 0 0 0 0 x1 0 1 2 3 4 x2 0 2 4 1 3 x3 0 3 1 4 2 x4 0 4 3 2 1 > X=Y=nn > outer(X,Y,waru) # WRONG!! [,1] [,2] [,3] [,4] [1,] 1 1 1 1 [2,] NA NA NA NA [3,] NA NA NA NA [4,] NA NA NA NA > a=expand.grid(X,Y) > b=matrix(mapply(waru,a[,1],a[,2]),length(X)) > rownames(b)=paste0('x',nn) > colnames(b)=paste0('y',nn) > b # x / y y1 y2 y3 y4 x1 1 3 2 4 x2 2 1 4 3 x3 3 4 1 2 x4 4 2 3 1 >>174 そりゃあ、outer に渡す関数がまずいんだろ。 outer に渡す関数は、完全にベクトル対応になっていなければならないんじゃないの? でなければ、わざわざ outer 使うこともなかろう。 >>175 レスありがとうございます。 自作関数から自作関数を呼び出しているのが原因かと思っていましたが、 ベクトル対応していないとはこういうことでしょうか? 加減乗は引数のどちらをベクトルにしても動作 > kake(1:4,1) [1] 1 2 3 4 > kake(1,1:4) [1] 1 2 3 4 > tasu(1:4,1) [1] 2 3 4 0 > tasu(1,1:4) [1] 2 3 4 0 > hiku(1:4,1) [1] 0 1 2 3 > hiku(1,1:4) [1] 0 4 3 2 除算は第2引数をベクトルにすると誤動作 > waru(1:4,1) [1] 1 2 3 4 > waru(4,1:4) [1] 4 1 >>176 outer から呼び出されたときの引数を見てみればわかるよ。たぶん1度しか呼ばれず、できあがりの行列の要素すべてを計算するための引数がベクトルで渡されているはずだから。 >>177 ありがとうございます。 outerのソースをみたら、こんな記述があったので、X,Yを同時にベクトルで与えても動作する関数でないとダメみたいでした。 FUN <- match.fun(FUN) Y <- rep(Y, rep.int(length(X), length(Y))) if (length(X)) X <- rep(X, times = ceiling(length(Y)/length(X))) FUN(X, Y, ...) # greatest common divisor gcd <- function(x,y) ifelse(x|y,ifelse(x*y,max(intersect((1:abs(x))[abs(x)%%(1:abs(x))==0],(1:abs(y))[abs(y)%%(1:abs(y))==0])),max(abs(x),abs(y))),NA) 非正整数対応すると長くなるなぁ > gcd(24,15) [1] 3 > gcd(16,15) [1] 1 > gcd(5,0) [1] 5 > gcd(-24,15) [1] 3 > gcd(-24,-15) [1] 3 > gcd(0,0) [1] NA ユークリッドの互除法をつかうとこんな感じ > GCD <- function(x,y){ + if(round(x)!=x | round(y)!=y) stop('Not integer') + if(!x&!y) return(NA) + a=max(c(abs(x),abs(y))) + b=min(c(abs(x),abs(y))) + if(!a*b) return(a) + r=integer() + r[1]=a + r[2]=b + i=1 + r[i+2]=r[i]%%r[i+1] + while(r[i+2]!=0 & r[i+2]!=1){ + i=i+1 + r[i+2]=r[i]%%r[i+1] + } + return(ifelse(r[i+2]==0,r[i+1],1)) + } > GCD(0,0) [1] NA > GCD(24,15) [1] 3 > GCD(16,15) [1] 1 > GCD(5,0) [1] 5 > GCD(24,-15) [1] 3 > GCD(-24,-15) [1] 3 > GCD(2.3,4) Error in GCD(2.3, 4) : Not integer #.n発r中の狙撃手が.N発狙撃するときの命中数を返す Go13 <- function(.N, .n, r, k=10^3){ # k:シミュレーション回数 f <-function(S,N=.N,n=.n){ y=c(rep(1,S),rep(0,N-S)) sum(sample(y,n)) } xx=r:.N SS=NULL for(i in 1:k){ x=sapply(xx,f) SS=c(SS,which(x==r)-1+r) } print(summary(SS)) invisible(SS) } こういう問題を考えるのは楽しいね。 ゴルゴ13は100発100中 ゴルゴ14は10発10中 ゴルゴ15は1発1中 とする。 各々10000発撃ったとき各ゴルゴの命中数の期待値はいくらか? ドツボ13は100発0中 ドツボ14は10発0中 ドツボ15は1発0中 とする。 各々10000発撃ったときドツボの命中数の期待値はいくらか? ベクトルは再利用されるんだな > c(1,2,1,2)==c(1,2) [1] TRUE TRUE TRUE TRUE > all(c(1,2,1,2)==c(1,2)) [1] TRUE > equal <- function(x,y) sum((x-y)^2)==0 & length(x)==length(y) > equal(c(1,2,1,2),c(1,2)) [1] FALSE > x= list(length=5) > x $length [1] 5 > y=list() > length(y)=4 > y [[1]] NULL [[2]] NULL [[3]] NULL [[4]] NULL > z=list(5) > z [[1]] [1] 5 > w = vector(mode="list" , length= 5) > w [[1]] NULL [[2]] NULL [[3]] NULL [[4]] NULL [[5]] NULL Brunner-Munzel検定って比較する両群に重なりがないとp値がNAになるんだが、 これってバグなのか? > x=1:5 > y=6:10 > lawstat::brunner.munzel.test(x,y) Brunner-Munzel Test data: x and y Brunner-Munzel Test Statistic = Inf, df = NaN, p-value = NA 95 percent confidence interval: NaN NaN sample estimates: P(X<Y)+.5*P(X=Y) 1 > x=1:6 > y=6:11 > lawstat::brunner.munzel.test(x,y) Brunner-Munzel Test data: x and y Brunner-Munzel Test Statistic = 24.749, df = 10, p-value = 2.651e-10 95 percent confidence interval: 0.9423463 1.0298759 sample estimates: P(X<Y)+.5*P(X=Y) 0.9861111 突然ですが質問があります。最近Rソフトを利用し始めた者のです。単刀直入に、 ボロノイ図を制作した場合に分割された面積の平均を出力するには、どうすればよいのでしょうか? 現状としては住所をグーグルマップの緯度経度に変換し、分割まではできています。 宜しければどなたかお力添えをいただけないでしょうか? ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる