トップページ数学
1002コメント395KB
【R言語】統計解析フリーソフトR 第6章【GNU R】 [無断転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
0001132人目の素数さん
垢版 |
2017/08/03(木) 19:23:12.67ID:Hq1blL0O
R は統計計算とグラフィックスのための言語・環境です。
統計計算で重宝するデータ型や、複数要素を処理する演算や関数、
解析結果を表示するグラフィックなど、多彩な機能を提供します。

●関連サイト
The R Project
http://www.r-project.org/
RjpWiki
http://www.okada.jp.org/RWiki/
リンク集
http://www.okada.jp.org/RWiki/?%A5%EA%A5%F3%A5%AF%BD%B8
※前スレ
【R言語】統計解析フリーソフトR 第5章【GNU R】
http://rio2016.2ch.net/test/read.cgi/math/1380168442/
0505132人目の素数さん
垢版 |
2018/09/03(月) 18:55:17.77ID:S47YTHgP
データを解析する前にさらっと特徴を見たい時、皆さんはどんなコマンドを使っていますか?

私が思いつくのは
summary
boxplot
hist
pairs

です。こんなのも良いよってのがあったら教えてくださいm(_ _)m

※ライブラリの使用有無は問いません
0509132人目の素数さん
垢版 |
2018/09/09(日) 22:35:22.23ID:9XY+z1xx
>>501
良い方法が見つからなかったので !length(x)で空白ベクトル判定とした。

文字列を逆に並べる再帰呼び出しスクリプト

> reverse <- function(x){
+ if(!length(x)) return(NULL)
+ c(Recall(x[-1]),x[1])
+ }
> cat(reverse(LETTERS[1:26]))
Z Y X W V U T S R Q P O N M L K J I H G F E D C B A
0512132人目の素数さん
垢版 |
2018/09/10(月) 18:22:05.74ID:gLTPxqtw
>>511
length は数値を返す関数なのに、なぜわざわざ論理演算をするんだ?
プログラムは、ここの議論を知らない人が読む可能性のほうが高いんだぞ。
0513132人目の素数さん
垢版 |
2018/09/10(月) 19:12:52.95ID:ZYY4OYkH
>>512
正規分布が一様分布より大きい期待値の算出に
mean(rnorm(100)>runif(100))
って書かない?
俺は
sum(ifelse(rnorm(100)>runif(100),1,0))/100
って書いたりしないけど。
0515132人目の素数さん
垢版 |
2018/09/10(月) 19:50:35.36ID:ZYY4OYkH
>>514
論理値を数値に置き換えて計算しているから
数値を論理値にしても別に違和感がない。
可読性は慣れの問題。
0517132人目の素数さん
垢版 |
2018/09/10(月) 21:30:23.37ID:gLTPxqtw
>>513
それとこれとは話が別だ。
logical は TRUE か FALSE の二値しかとらないから、それから数値への変換は自明。
多種の値をとる数値に論理演算をするのはいただけない。
0518132人目の素数さん
垢版 |
2018/09/10(月) 21:36:20.92ID:gLTPxqtw
>>515
is.empty.vector のような関数があるならそれでよいが、length を使っているのだから、それを勝手にベクトルが空かどうかの判断に使っているのはあなたであって、他人はそのようには考えない、といっているのだ。
自分だけしかこーどを見ないならべつに構わないが、こういうところに晒すのはよくない。
ましてや常套手段などと言って他人に教え込むのはやめてもらいたい。
0520132人目の素数さん
垢版 |
2018/09/10(月) 21:55:50.32ID:5QS5/GHY
whileの中は1でも2でもよくね?

n=0
while(1){
if(n>10) return(10)
n=n+1
}


n=0
while(2){
if(n>10) return(10)
n=n+1
}
0521132人目の素数さん
垢版 |
2018/09/10(月) 22:00:57.10ID:5QS5/GHY
>509は
配列を逆順に並べる再帰呼出しのコード。

Rにはrevという関数がある。

そのコードみてみ!

lengthを真偽判定に使ってますがな。


> base:::rev.default
function (x)
if (length(x)) x[length(x):1L] else x
0524132人目の素数さん
垢版 |
2018/09/11(火) 08:48:42.34ID:QUqp/jpE
!を引数が数値のときは0か否かを返す関数と理解すれば
if(!0) print(!1)の結果もサクッとわかる。
0525132人目の素数さん
垢版 |
2018/09/11(火) 09:08:32.20ID:QUqp/jpE
数値を非零かどうか論理値に変換して処理するかは
関数によるな。

if やwhileは変換処理しているけど
whichだとエラーになるな。

> which(!0)
[1] 1
> which(0)
Error in which(0) : argument to 'which' is not logical
> which(2)
Error in which(2) : argument to 'which' is not logical
> which(!3)
integer(0)
>
0526132人目の素数さん
垢版 |
2018/09/11(火) 09:12:56.04ID:QUqp/jpE
!ってベクトル対応しているな
> which(!(-1:1))
[1] 2
> !(-2:2)
[1] FALSE FALSE TRUE FALSE FALSE
0529132人目の素数さん
垢版 |
2018/09/15(土) 16:45:38.59ID:h0gUCZ3r
>>525
だいたい、if や while は関数じゃないし。
while (1) などと書くのはCに毒されているんじゃねーの?
Rなら while (TRUE) のほうが良いし、repeat というのもある。
0530132人目の素数さん
垢版 |
2018/09/15(土) 16:45:41.31ID:Vl7XZ52q
>>528
スクリプトを読むときに脳内変換する癖をつけておけば
可読性が悪いと思わずにすむ。
0532132人目の素数さん
垢版 |
2018/09/15(土) 17:19:35.45ID:h0gUCZ3r
>>531
Rのライブラリ?の書き方なんてあてにならないよ。
そもそも、rev も 509 の reverse も演算の回数を必要最低限にするなら、条件は length(x)) >= 2 または > 1 だ。
まあ if (length(x)) のほうが速かったのかも知れないが、常にそうなるとは限らないのだから、早すぎる最適化は諸悪の根源だ。
0533132人目の素数さん
垢版 |
2018/09/15(土) 19:30:34.55ID:Vl7XZ52q
可読性の次は速度かよ。
自分の流儀と違う { の使い方でも文句いいそう。
0534132人目の素数さん
垢版 |
2018/09/15(土) 19:44:27.43ID:VibLIqgl
0,1を1000万個作って
!
!=
>
==
での真偽判定を各々10回する時間を出してみた。


> x=rbinom(1e7,1,0.5)
> system.time(replicate(10,!x))
user system elapsed
1.27 0.33 1.59
> system.time(replicate(10,x!=0))
user system elapsed
2.39 0.36 2.75
> system.time(replicate(10,x>0))
user system elapsed
2.58 0.31 2.92
> system.time(replicate(10,x==1))
user system elapsed
2.60 0.36 2.99
0535132人目の素数さん
垢版 |
2018/09/15(土) 19:57:45.72ID:VibLIqgl
!x と x!=0 で10回やったが、

> f <- function(){
+ x=rbinom(1e7,1,0.5)
+ (a=system.time(!x)[3])
+ (b=system.time(x!=0)[3])
+ a<b
+ }
> (re=replicate(10,f()))
elapsed elapsed elapsed elapsed elapsed elapsed elapsed elapsed elapsed
TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
elapsed
TRUE

結果は再現された。
0536132人目の素数さん
垢版 |
2018/09/15(土) 20:06:37.73ID:VibLIqgl
lengthが絡むと

> x=1:1e8
> f1 = function(x) if(!length(x)) return(NULL) else x=x[-1]
> f2 = function(x) if(length(x)==0) return(NULL) else x=x[-1]
> system.time(f1(x))
user system elapsed
2.38 0.53 2.93
> system.time(f2(x))
user system elapsed
2.05 0.61 2.69

御指摘の通り、!の負け
0537132人目の素数さん
垢版 |
2018/10/04(木) 17:02:48.04ID:247Ted9r
>>444
>遅レスだが、Ubuntu 18.04LTSならデフォルトのIBus-mozcで日本語入力ができるそうだ。
>詳しくはUbuntu Weekly Recipeの第527回を読んでくだされ

Ubuntu 18.04.1 LTSにアップグレードしたけどできない
いままでスクレイピングにつかってrvestのログインコマンドもエラー出るようになったし最悪だ。。。。
0538132人目の素数さん
垢版 |
2018/10/04(木) 20:04:49.68ID:W6fWyA5T
アップグレードってことは文字入力がFcitxのままになってない?Fcitxならパッチ要だよ。
Voyager 18.04LTS(xubuntu 18.04LTS)ではパッチなしでRStudioに日本語入力できた。
0539132人目の素数さん
垢版 |
2018/10/26(金) 12:58:59.43ID:8LsI2NoU
昨日、PCを新しくして最新のR入れたんだけど、
作業ディレクトリの固定化できなくね?
前まではショートカットのプロパティで作業フォルダ指定してたんだけど、
新しいR、何度やっても作業ディレクトリがデフォルトのドキュメントに戻りやがる

どうすればいいか、誰がご教示を。
0540132人目の素数さん
垢版 |
2018/10/26(金) 13:04:50.23ID:I9GOHEF6
>>539
プロパティでコマンドラインオプションを消せばよい。
--cd-ほにゃらら
というのが付いてるでしょ。
0542132人目の素数さん
垢版 |
2018/10/26(金) 23:05:34.11ID:5yNEfvRx
xtsの取り扱い方について質問失礼します。
以下のコードで、dataには2018/10/20 00:00〜2018/10/25 00:00の1時間刻みのaとbの値のxts型オブジェクトが入りますが、(aとbは時系列データのイメージです)
このdataの毎日09:00の値を添え字を使って取り出す方法はありますか?
(data["2018-10-21 00:00"]とすると10/21の00:00が取り出せるような感じで)

library(xts)
time <- seq(as.POSIXct("2018-10-20 00:00"), as.POSIXct("2018-10-25 00:00"), by="1 hour")
a <- rnorm(length(time))
b <- rnorm(length(time))
data <- xts(x = cbind(a,b), order.by = time)

思いついたのはfor文を使って以下のようにするのかなと思ったのですがもう少しいい方法があるだろうなと思いまして…

data_result <- data[10] # まずxts型の入れ物を作る(2018/10/20 09:00)
for (i in 1:4) {
data_result <- rbind(temp,data[10+24*i]) # 2日目以降はこれにくっつける
}
data_result
0543132人目の素数さん
垢版 |
2018/10/26(金) 23:12:48.52ID:Xg1/ChR5
失礼、>>542の下のコードはこっちです

data_result <- data[10] # まずxts型の入れ物を作る(2018/10/20 09:00)
for (i in 1:4) {
data_result <- rbind(data_result, ,data[10+24*i]) # 2日目以降はこれにくっつける
}
data_result
0546132人目の素数さん
垢版 |
2018/11/01(木) 22:44:27.08ID:xCdOvDq8
巨大数を扱えるというふれこみのRmpfrって正確じゃないな。
50の階乗を計算させてみた

R with Rmpfr
> mpfr(factorial(50),1e5)
1 'mpfr' number of precision 100000 bits
30414093201713018969967457666435945132957882063457991132016803840

Haskell:
Prelude> product[1..50]
30414093201713378043612608166064768844377641568960512000000000000

Python:
import math
print(math.factorial(50))
30414093201713378043612608166064768844377641568960512000000000000

Wolfram:
https://www.wolframalpha.com/input/?i=50!
30414093201713378043612608166064768844377641568960512000000000000
0548132人目の素数さん
垢版 |
2018/11/03(土) 09:32:49.16ID:NiwdVATo
R3.5.xから、Windows環境だと日本語パスまわりでエラーがでてどうにもならない
enc2native()しても駄目だし
とりあえずcairo_png()だけでも…
0549132人目の素数さん
垢版 |
2018/11/03(土) 10:31:12.42ID:pqZePX+I
一度つかって日本語周りの処理でエラー出てきたんで未だに3.4.4浸かってる
0550132人目の素数さん
垢版 |
2018/11/04(日) 21:55:16.95ID:lTCeMsqQ
統計の質問はこのスレでいいんだろうか?

ある医院に1時間あたり平均5人の患者が来院し、その人数の分布はポアソン分布にしたがうとする。
1時間あたりの平均診療人数は6人で、一人あたりの診療時間は指数分布に従うとする。
診察までの平均の待ち時間は何時間か?

このシミュレーション解はこれであってる?

N=1e6
λ=5
μ=6
sum(rpois(N,λ)*rexp(N,μ))/N

> sum(rpois(N,λ)*rexp(N,μ))/N
[1] 0.8331036

60かけて、分にすると
[1] 49.86565
0551132人目の素数さん
垢版 |
2018/11/08(木) 12:35:54.73ID:wKTjJ6Fa
>>306
grep 使って書いてみた。
# mhs(c(1,0,1,1,0,1,1,1)) : return 3
mhs = function(x){ # maximum head sequence
y=paste(x,collapse='')
str="1"
if(!grepl(str,y)) return(0)
else{
while(grepl(str,y)){
str=paste0(str,"1")
}
return(nchar(str)-1)
}
}

system.time(mean(replicate(1e4,mhs(sample(0:1,100,rep=T))>=5)))


# N(=100)回コインをn(=5回)以上続けて表がでるか?TRUE or FALSE
seqn<-function(n=5,N=100,p=0.5){
rn=rbinom(N,1,p)
count=0
for(i in 1:N){
if(rn[i] & count<n){
count=count+1
}
else{
if(count==n) {return(TRUE)}
else{
count=0
}
}
}
return(count==n)
}

system.time(mean(replicate(1e4,seqn())))


結果は、
> system.time(mean(replicate(1e4,mhs(sample(0:1,100,rep=T))>=5)))
user system elapsed
4.56 0.01 4.61
> system.time(mean(replicate(1e4,seqn())))
user system elapsed
1.05 0.00 1.07

逆に4倍時間がかかるようになった
0553132人目の素数さん
垢版 |
2018/11/08(木) 15:13:38.19ID:UNhl34kg
coinの表裏を1と0で表して、その累積和を取ったベクトルを用意して
そのベクトルの5個前とのdiffの要素の中に5が一回でも現れることが、一回でも5回連続で表が出たことがあることの必要十分条件
grepはどうしても時間がかかるしif文もできれば使いたくない

searchseq <- function(n=5,N=100,p=0.5,trial=10000){
result <- 0 # 表が5回以上出た回数を数える入れ物
for (i in 1:trial){
coin <- rbinom(N,1,p)
coincumsum <- cumsum(coin)
coindiff <- diff(coincumsum,5)
#diff(coincumsum,5)の要素に一個でも5があれば表が5回以上出たことがあったということ
#anyでT/Fにして、sumで0/1にする
result <- result+sum(any(coindiff==5))
}
return(result/trial)
}

結果もよさそう
> searchseq()
[1] 0.80793

> system.time(mean(replicate(10000,mhs(sample(0:1,100,rep=T))>=5)))
ユーザ システム 経過
0.92 0.00 0.93
> system.time(mean(replicate(10000,seqn())))
ユーザ システム 経過
0.29 0.00 0.30
> system.time(searchseq())
ユーザ システム 経過
0.21 0.00 0.20
0555132人目の素数さん
垢版 |
2018/11/08(木) 23:32:48.68ID:/ZlhhGjJ
>>553
レスありがとうございました。

rleとも比べてみました。

> system.time(mean(replicate(1e4,seqn())))
user system elapsed
4.290 0.000 4.377
>system.time(mean(replicate(1e4,max(rle(rbinom(100,1,0.5))$len)>=5)))
user system elapsed
3.620 0.000 3.742
> system.time(mean(replicate(1e4,mhs(rbinom(100,1,0.5)>=5))))
user system elapsed
2.390 0.000 2.435
> system.time(searchseq())
user system elapsed
1.880 0.000 1.988
0556132人目の素数さん
垢版 |
2018/11/08(木) 23:35:10.38ID:/ZlhhGjJ
>>555
greplの逆転はsampleをrbinomに変えたためでしょう。

> system.time(replicate(1e5,sample(0:1,100,rep=T)))
user system elapsed
7.200 0.180 7.591
> system.time(replicate(1e5,rbinom(100,1,0.5)))
user system elapsed
5.980 0.230 6.319
0559132人目の素数さん
垢版 |
2018/11/09(金) 02:01:36.95ID:Qla0VxTD
>>558
ご指摘ありがとうございました。
修正しました。
rle1 <- function(N=100,n=5,p=0.5){
r=rle(rbinom(N,1,p))
max(r$len[which(r$val==1)])
}
結果
> system.time(mean(replicate(1e4,max(rle1()>=5))))
user system elapsed
4.430 0.000 4.546
> system.time(mean(replicate(1e4,seqn())))
user system elapsed
4.490 0.010 4.609
> system.time(mean(replicate(1e4,mhs(rbinom(100,1,0.5))>=5)))
user system elapsed
7.440 0.000 7.656
> system.time(searchseq())
user system elapsed
1.950 0.000 2.066
>
0560132人目の素数さん
垢版 |
2018/11/09(金) 07:25:00.97ID:Qla0VxTD
無理矢理1行にして実行

system.time(mean(replicate(1e4,any(diff(cumsum(rbinom(100,1,0.5)),5)==5))))
user system elapsed
1.820 0.000 1.886
>
> system.time(mean(replicate(1e4,with(rle(rbinom(100,1,0.5)), max(lengths[wh
<e(1e4,with(rle(rbinom(100,1,0.5)), max(lengths[whi ch(values==1)])>=5))))
user system elapsed
4.370 0.010 4.478
0561132人目の素数さん
垢版 |
2018/11/09(金) 07:59:47.47ID:rijPDFSR
>>560
意味もなくforループ回してた上に毎回sum使って真偽値を数値に変換してたけど
replicate使って最後に一回だけmean取ると2.066→1.886で1割短くなるのね
他人のコード読むのは勉強になる
0563132人目の素数さん
垢版 |
2018/11/09(金) 09:44:07.41ID:5AnUTlVm
>>559
全部が0のとき、エラーになるので修正

rle01 <- function(x){ # c(0,1,1,1,0,0) => return 3
if(sum(x)==0) return(0) #c(0,0,0,0,0,0) => return 0
else{
r=rle(x) # Run Length Encoding
max(r$lengths[which(r$values==1)]) # max length of value 1
}
}

動作確認

> rle01(x<-rbinom(100,1,0.5)) ; x
[1] 8
[1] 1 1 0 1 0 1 0 0 0 1 1 1 0 1 0 0 0 0 1 0 0 0 1 1 1 1 0 0 1 1 1 1 1 0 0
[36] 1 1 0 1 1 1 0 1 1 0 0 1 1 0 1 1 1 0 1 1 0 0 1 1 0 1 0 1 1 0 1 0 1 0 0
[71] 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 0 0 1 0 0 1 1 1 0 1 1
> rle01(x<-rbinom(100,1,0)) ; x
[1] 0
[1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[36] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[71] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0564132人目の素数さん
垢版 |
2018/11/09(金) 10:10:01.39ID:Ui6BpICy
>>563
センスないなあ。
rle01 <- function(x) {
r <- rle(x)
one <- r$values == 1
if (any(one)) max(r$length[one]) else 0
}
0565132人目の素数さん
垢版 |
2018/11/09(金) 10:40:31.84ID:5AnUTlVm
>>564
whichは余分でした。

sumの方がrleより高速だと思ったらから、すべて0の場合はrleを呼ばないことにしただけ。
0連続でやるとこれだけ差がつく。

rle01 <- function(x){ # c(0,1,1,1,0,0) => return 3
if(sum(x)==0) return(0) #c(0,0,0,0,0,0) => return 0
else{
r=rle(x) # Run Length Encoding
max(r$lengths[which(r$values==1])] # max length of value 1
}
}
rle012 <- function(x) {
r <- rle(x)
one <- r$values == 1
if (any(one)) max(r$length[one]) else 0
}

> x=rep(0,1e8)
> system.time(rle01(x))
user system elapsed
0.3 0.0 0.3
> system.time(rle012(x))
user system elapsed
7.36 4.52 13.25
>
0566132人目の素数さん
垢版 |
2018/11/09(金) 10:52:23.39ID:Ui6BpICy
>>565
そんな特別な場合のことに対して高速化するのは愚の骨頂。
1が一つでもある場合にsumを呼ぶのは余計じゃないのか?
余計なwhichがあるくらいだから、まずは素直にやりたいこと、やるべきことを正しく書くようにしたら?
0567132人目の素数さん
垢版 |
2018/11/09(金) 11:01:40.74ID:5AnUTlVm
1000本に1本あたる宝クジを100本買って続けて2本あたる確率のシミュレーション解の算出時間比較。
確率の理論値は9.8897353347449091e-05

> system.time(mean(replicate(1e4,rle01(rbinom(N,1,p))>=n)))
user system elapsed
0.61 0.00 0.64

> system.time(mean(replicate(1e4,rle12(rbinom(N,1,p))>=n)))
user system elapsed
1.97 0.00 2.03
0569132人目の素数さん
垢版 |
2018/11/09(金) 19:43:44.34ID:0M0agNOf
JPXのデータ、ファイル形式csvを読み込もうとするとうまく行かないんですが
どんな引数をつければいいですか
0571132人目の素数さん
垢版 |
2018/11/10(土) 11:20:41.80ID:QJ6NJqU7
コインを100回ふったときの表連続の最大数が5であったときの
このコインの表がでる確率の期待値、モード比、信頼区間を求めるのが次のネタ。

unirootで算出できたけど
シミュレーションはどうすればいいのかアイデアが浮かばない。
MCMCで解決できるかなぁ?

これをシミュレーションで検証したい。

$Rscript main.r
lower mean mode upper
0.2487456 0.4469764 0.4589692 0.6386493

http://tpcg.io/asKRE9
0572132人目の素数さん
垢版 |
2018/11/11(日) 20:11:21.81ID:ODPKEEGK
1億回のコイントスで何回連続して表がでる確率が高いかRでやってみた。

# maximal sequential head probability at 10^8 coin flip
> y
[1] 2.2204460492503131e-16 2.2204460492503131e-16
[3] 8.8817841970012523e-16 1.5543122344752192e-15
[5] 3.5527136788005009e-15 6.8833827526759706e-15
[7] 1.4210854715202004e-14 2.8199664825478976e-14
[9] 5.6843418860808015e-14 1.1346479311669100e-13
[11] 2.2737367544323206e-13 4.5452530628153909e-13
[13] 9.0949470177292824e-13 1.8187673589409314e-12
[15] 3.6379788070917130e-12 7.2757355695785009e-12
[17] 1.4551915228366852e-11 2.9103608412128779e-11
[19] 5.8207660913467407e-11 1.1641509978232989e-10
[21] 6.6493359939245877e-06 2.5720460687386204e-03
[23] 4.8202266324911647e-02 1.7456547460031679e-01
[25] 2.4936031630254019e-01 2.1428293501123058e-01
[27] 1.4106434838399229e-01 8.1018980443629832e-02
[29] 4.3428433624081136e-02 2.2484450838189007e-02

25回が続くのが4回に1回あることになる。
pythonで25回以上と25回ちょうどになるのを計算させてみた。

その結果、
Over 25
6977459029519597/9007199254740992
= 0.7746535667951356
Just 25
2246038053550679/9007199254740992
= 0.24936031612362342

高速化を狙ってCに移植したら
100万回で暴走。
https://egg.5ch.net/test/read.cgi/hosp/1540905566/132
0573132人目の素数さん
垢版 |
2018/11/12(月) 21:04:57.19ID:boi8bvdM
"マラソン大会の選手に1から順番に番号の書かれたゼッケンをつける。
用意されたゼッケンN(=100)枚以下の参加であった。
無作為に抽出したM(=5)人のゼッケン番号の最大値はMmax(=60)であった。
参加人数推定値の期待値とその95%信頼区間を求めよ"

decken <- function(M, Mmax, N, conf.level=0.95){
if(Mmax < M) return(0)
n=Mmax:N
pmf=choose(Mmax-1,M-1)/choose(n,M)
pdf=pmf/sum (pmf)
mean=sum(n*pdf)
upr=n[which(cumsum(pdf)>conf.level)[1]]
lwr=Mmax
c(lower=lwr,mean=mean,upper=upr)
}
decken(M=5,Mmax=60,N=100)

> decken(M=5,Mmax=60,N=100)
lower mean upper
60.0000 71.4885 93.0000

これをシミュレーションで確認したい。

# simulation
M=5 ; Mmax=60 ; N=100
sub <- function(M,Mmax,N){
n=sample(Mmax:N,1) # n : 参加人数n
m.max=max(sample(n,M)) # m.max : n人からM人選んだ最大番号
if(m.max==Mmax) return(n)
}
sim <- function(){
n=sub(M,Mmax,N)
while(is.null(n)){
n=sub(M,Mmax,N) # 最大番号が一致するまで繰り返す
}
return(n)
}
runner=replicate(1e4,sim())
summary(runner) ; hist(runner,freq=F,col="lightblue")
quantile(runner,prob=c(0,0.95))
cat(names(table(runner)[which.max(table(runner))]))

> summary(runner) ; hist(runner,freq=F,col="lightblue")
Min. 1st Qu. Median Mean 3rd Qu. Max.
60.00 63.00 68.00 71.43 77.00 100.00
> quantile(runner,prob=c(0,0.95))
0% 95%
60 93
> cat(names(table(runner)[which.max(table(runner))])) # 最頻値
60

結果は確認できたけど、もっと高速なシミュレーションアルゴリズムはあるだろうか?
0574132人目の素数さん
垢版 |
2018/11/16(金) 13:44:59.80ID:U19cHKqd
重複があるか否かを返す、anyDuplicatedという関数を知ったので総当たり比較と早いかどうか比べてみた。
覆面算を □/□ * □/□ = □□/□を解くの使ってみた。
a/b * c/d == ef/g (c>a)として

F = function(fun){
n=1:9
ans=NULL
for(a in n){
for(b in n){
for(c in a:9){
for(d in n){
for(e in n){
for(f in n){
for(g in n){
if(fun(a,b,c,d,e,f,g)){
ans=rbind(ans,c(a,b,c,d,e,f,g))}}}}}}}}

return(ans)
}
で虱潰しに判定

F1=function(a,b,c,d,e,f,g){ #全部の組み合わせが等しくないのを確認
(a/b)*(c/d)==(10*e+f)/g &
a!=b & a!=c & a!=d & a!=e & a!=f & a!=g &
b!=c & b!=d & b!=e & b!=f & b!=g & c!=d &
c!=e & c!=f & c!=g & d!=e & d!=f & d!=g & e!=f & e!=g & f!=g
}

F2=function(a,b,c,d,e,f,g){ # anyDuplicatedで重複なしを判定
(a/b)*(c/d)==(10*e+f)/g & !anyDuplicated(c(a,b,c,d,e,f,g))
}

> system.time(F(F1))
user system elapsed
52.56 0.25 53.38
> system.time(F(F2))
user system elapsed
113.78 0.11 115.81

anyDuplicatedでコードは短くなるが速さが犠牲になった。
0576132人目の素数さん
垢版 |
2018/11/18(日) 12:56:58.01ID:tDkQkz0a
初歩的な質問で恐縮ですが、
truehistで出したヒストグラムの情報をテキストファイルとして保存する方法、教えて頂けませんか?
0578132人目の素数さん
垢版 |
2018/11/18(日) 17:12:37.03ID:HQweHJGH
>>576
MASS::truehist
でソースを覗いたら最後はinvisible()になっていた。
ここを
return(list(breaks=breaks,h=h,nbins=nbins,xlab=xlab))
にしたら

$`breaks`
[1] -0.001 0.999 1.999 2.999 3.999 4.999 5.999 6.999 7.999 8.999 9.999 10.999 11.999
[14] 12.999 13.999

$h
[1] 1

$nbins
[1] 17

$xlab
[1] "x"
で出力されるけど、
どのパラメータがあればヒストグラムが再現できるのかは不勉強にてわからない。
0580132人目の素数さん
垢版 |
2018/11/18(日) 20:37:19.22ID:HQweHJGH
>>579
レスありがとうございます。
すると
truehist のソースの最後の
invisible()

return(list(breaks=breaks,est=est))
として、breakの中点を横軸、estを縦軸にするとヒストグラムが再現できるわけですね。
0581132人目の素数さん
垢版 |
2018/11/18(日) 20:40:50.06ID:HQweHJGH
invisible() → return(list(breaks=breaks,est=est))
に改造したソースをtruehist0として

midpoint <- function(x){ # c(1,2,3,4) -> c(1.5,2.5,3.5)
n=length(x)
mpt=numeric(n-1)
for(i in 1:(n-1)){
mpt[i]=mean(x[i],x[i+1])
}
return(mpt)
}
x=rnorm(10000)
(data=truehist0(x))
with(data, plot(midpoint(breaks),est,type='h',lwd=5,col='cyan'))

で元のヒストグラムが再現できた。
0582132人目の素数さん
垢版 |
2018/11/18(日) 20:52:08.49ID:HQweHJGH
graphics:::hist.default

でhistのソースを表示させてみた。

r <- structure(list(breaks = breaks, counts = counts, density = dens,
mids = mids, xname = xname, equidist = equidist), class = "histogram")
if (plot) {
plot(r, freq = freq1, col = col, border = border, angle = angle,
density = density, main = main, xlim = xlim, ylim = ylim,
xlab = xlab, ylab = ylab, axes = axes, labels = labels,
...)
invisible(r)
}

histでのcountsが
truehistではestと呼ばれているようだ。

estimateの略かな?
0583132人目の素数さん
垢版 |
2018/11/20(火) 18:37:20.95ID:kwMT/Yc9
どいつもこいつもナイル川で説明しやがって
データの操作が一番むずいんだよ!
0584132人目の素数さん
垢版 |
2018/11/21(水) 12:43:45.15ID:4Qrr7yQM
あるデータ群に対して、確率密度関数のパラメータをフィッティングさせる方法ってないですか?
ちなみに、フィッティングさせたいのはレブィフライト確率密度関数です。
0587132人目の素数さん
垢版 |
2018/11/21(水) 21:59:06.34ID:kb0MtFao
>>584-585

とりあえず、最小二乗法でやってみた。

ガンマ分布の乱数を近似してみた。

dlevy <- function (x,m,c) sqrt(c/2/pi)*exp(-c/2/(x-m))/(x-m)^3/2
set.seed(123)
dat=rgamma(1e3,1) ; hist(dat,freq=F)
x=density(dat)$x ; y=density(dat)$y
lines(x,y)
f<-function(mc){
m=mc[1];c=mc[2]
sum((y-dlevy(x,m,c))^2)
}
(mc=optim(c(0,1),f, method='N')$par)
curve(dlevy(x,mc[1],mc[2]),add=T,col=2)
0588132人目の素数さん
垢版 |
2018/11/21(水) 23:39:04.38ID:8W1KB4Wk
>>586
fitdistは対応できる分布が限定されているから
のソースを改造しないと無理だな。
0589132人目の素数さん
垢版 |
2018/11/22(木) 19:54:16.79ID:bptUComJ
ソースが長かったので

sink('print.out')
print(MASS::fitdistr)
sink()

でprint.outに出力してみた。

これもoptimを使っているようだが、最小二乗法なのかどうなのかわからなかった。
0591132人目の素数さん
垢版 |
2018/11/23(金) 18:16:00.74ID:rwOyVQ2V
>>590
レスありがとうございます。

λ=5
μ=6
N=1e6
sum(rpois(N,λ)*rexp(N,μ))/N

> sum(rpois(N,λ)*rexp(N,μ))/N
[1] 0.833631

ρ=λ/μ
ρ/(1-ρ)
ρ/(1-ρ)*1/μ
> ρ/(1-ρ)*1/μ
[1] 0.8333333

なのでいいのだろうとは思っていたのですが、時系列のシミュレーションは自信がありませんでした。
0592132人目の素数さん
垢版 |
2018/11/23(金) 21:47:20.33ID:rwOyVQ2V
>>591
>550の設定で12分毎に患者が来院したら、待ち時間は全員0だと思うのだが

ρ/(1-ρ) の公式って正しいんだろうかな?
0594132人目の素数さん
垢版 |
2018/11/27(火) 11:01:28.21ID:V3tvhpxu
>>592
自己レス
公式は定常状態に達したときという前提での計算なんだな。

MMS = function(n, lamda=5,mu=6,s=1){
rho=lamda/mu
sig=0
for(i in 0:s) sig=sig+rho^i/factorial(i)
p0=1/( sig + rho^(s+1)/factorial(s)/(s-rho) )
ifelse(n >= s, rho^n/factorial(s)/s^(n-s)*p0, rho^n/factorial(n)*p0)
}

E=0
for(i in 0:1000) E=E+i*MMS(i)

> E
[1] 5
0596132人目の素数さん
垢版 |
2018/11/27(火) 16:44:04.82ID:V3tvhpxu
>>595
こういう類の待ち時間の話。

ある医院では、患者が平均10分間隔でポアソン分布にしたがって訪ねてくることがわかった。
医者は1人であり、1人の患者の診療にかかる時間は平均8分の指数分布であった。
「平均待ち時間」を5分以下にするには同じ診察効率の医師が何人に必要か?
その最小人数で「平均待ち時間」を5分以下に保って診療するには1時間に何人まで受付可能か?


公式に当て嵌めれば解けるのだけど
どうやってシミュレーションすればいいのか思い浮かばない。
コイントスやサイコロだとシミュレーションは容易なんだが。
0597132人目の素数さん
垢版 |
2018/11/28(水) 14:59:50.66ID:r8zTzMor
# シミュレーションしたみたが、結果が合致しない(特定のseedでは合致したけど)

# ある医院に1時間あたり平均5人の患者が来院し、その人数の分布はポアソン分布にしたがうとする。
# 1時間あたりの平均診療人数は6人で、一人あたりの診療時間は指数分布に従うとする。
# 診察までの平均の待ち時間は何時間か?

MM1sim <- function(n=40,lambda=5/60,mu=6/60,seed=FALSE,Print=TRUE){
# service starc clock time(ssct) since 9:00
ssct=numeric(n)
# waiting time(w8)
w8=numeric(n)
# service end clock time(sect)
sect=numeric(n)
# arrival clock time(act)
if(seed) set.seed(1234) ;
act=round(cumsum(rexp(n,lambda)))
# duration of service(ds)
if(seed) set.seed(5678) ;
ds=round(rexp(n,mu))

# simulation assuming service starts at 9:00
head(act) # act : arrival clock time
head(ds) # ds : duration of service
# initial values
ssct[1]=act[1] # 9:15 service start clock time for 1st guest
sect[1]=act[1]+ds[1] # 9:25 sevice end clock time for 1st guest
w8[1]=0


for(i in 2:n){
w8[i]=max(sect[i-1]-act[i],0)
ssct[i]=max(sect[i-1],act[i])
sect[i]=ssct[i]+ds[i]
}
if(Print){
print(summary(w8))
hist(w8,freq=FALSE,col="lightblue",main="")
}
invisible(w8)
}

w8m=replicate(1e3,mean(MM1sim(P=F)))
summary(w8m)
0598132人目の素数さん
垢版 |
2018/11/28(水) 15:00:27.16ID:r8zTzMor
途中の計算サンプル

# simulation step by step
#
# act[2] # 9:16 arrival clock time of 2nd
# max(sect[1]-act[2],0) # 9:25-9:16 vs 0 = ?sevice for 1st ends b4 2nd arrival
# w8[2]=max(sect[1]-act[2],0) # 9 min : w8ing time of 2nd
# ssct[2]=max(sect[1],act[2]) # 9:25 vs 9:16 = service start clock time for 2nd
# sect[2]=ssct[2]+ds[2] # 9:25 + 8 = 9:33 service end clock time for 2nd
#
# act[3] # 9:17 arrival clock time of 3rd
# max(sect[2]-act[3],0) # 9:33 - 9:17 vs 0 = ?serivce for 2nd ends b4 3rd arrival?
# w8[3]=max(sect[2]-act[3],0) # 16 min : w8ting time of 3rd
# ssct[3]=max(sect[2],act[3]) # 9:33 vs 9:17 = service start clock time for 3rd
# sect[3]=ssct[3]+ds[3] # 9:33 + 11 = 9:44 service end clock time for 3rd
#
0599132人目の素数さん
垢版 |
2018/11/28(水) 19:28:45.39ID:r8zTzMor
>>597
患者来院数40人程度では定常状態に達しないということみたいだな。

10万人での待ち時間の分布(理論値50に近い)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.000 5.532 28.619 47.540 67.370 528.511

100人での待ち時間の分布 (シミュレーションの度にばらつく)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.000 6.958 16.564 22.200 31.652 109.204

40人来院を1万回繰り返した平均の分布
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.304 11.764 19.357 25.449 32.536 177.913

ここに上げておきました。
http://tpcg.io/7psmrQ

結局のところ、待ち時間行列の理論を個人医院に適応しても
定常状態(待ち行列の長さが一定)に達していないと実用性がなさそうだな。

シミュレーションはなんとなく機能していた感じ。

ここに上げておきました。
https://www.tutorialspoint.com/tpcg.php?p=7psmrQ
http://tpcg.io/7psmrQ
0600132人目の素数さん
垢版 |
2018/11/29(木) 18:50:23.24ID:GEvMs+K3
来院患者数と待ち時間シミュレーションの結果をグラフにしてみた。
個人医院で待ち行列の長さが一定になるほどの受診があるとは考えがたいからこっちの方が現実に即しているんじゃなかろうか
と思うが、解析解はどんなふうになるのか想像もつかん。

https://i.imgur.com/tCOoxF7.png
0601132人目の素数さん
垢版 |
2018/12/01(土) 18:03:07.99ID:gm1XmpT3
初歩的な質問ですいません
truehistで軸を対数軸にして表示する方法って分かりますか?
0604132人目の素数さん
垢版 |
2018/12/02(日) 08:28:26.92ID:gEGEypwn
histで縦軸を対数表示させるならこんな感じかな。

with(hist(c(rnorm(1e6),rnorm(1e5,5,0.5))),plot(mids,log10(counts),type='h',col=4,lwd=10))

truehistだとソース改造すればいい。
■ このスレッドは過去ログ倉庫に格納されています