發信人cjlu.bbs@bbs.wretch.cc (路人甲),
看板Statistics
標 題Re: [問題] R算間距cdf
發信站無名小站 (Wed Jan 30 00:22:03 2008)
轉信站ptt!Group.NCTU!grouppost!Group.NCTU!wretch
※ 引述《bcs.bbs@ptt.cc (= ="frailty..gggg XD)》之銘言:
> 我想先給定一個間距,然後讓算每個間距的cdf值,但是pp的值卻都是0?
> 若改成 pexp(brck[2],theta)-pexp(brck[1],theta)則可算出第一個值
> 請問下面的迴圈是否有寫錯的?
> 謝謝
>
> for (i in 1:8){
> theta<-1/20
> brck<-c(0,9,18,27,36,45,54,63,72,200)
> pp<-numeric(11)
> pp[i]<-pexp(brck[i+1],theta)-pexp(brck[i],theta)
> }
>
這個迴圈的計算除了如接話所指出
將第四行的 pp<-numeric(11) 改為 pp<-numeric(0)
然後放到迴圈的外頭就可執行外,
應還有可改進的.
首先, 第二與第三行是數值的設定儲存, 無涉迴圈計算,
所以應提至迴圈外.
若檢視第五行, 會發現所需作的差量計算, 是針對 pexp(..., theta) 的值;
而此 pexp() 的值是可以在迴圈前就計算出來的.
(順帶一提, brck 共有十個值, 因此 pp 應有九個值, 而非八個!)
rate <- 1/20
brck <- c(0, 9, 18, 27, 36, 45, 54, 63, 72, 200)
prob <- pexp(brck, rate)
pp <- numeric(9)
for(i in 1:9)
pp[i] <- prob[i + 1] - prob[i]
其中, 我將原先命名為 theta 的改為 rate, 這直接對應到 pexp() 裡的選項名稱.
這改了似乎比原程式還多了一行, 但是細看一下, 就可發現第一至第三行可以合併為
prob <- pexp(c(0, 9, 18, 27, 36, 45, 54, 63, 72, 200), 1/20)
而第四至六行的迴圈計算, 也可(或是應)利用 R 在向量計算上的能力
(其實整併第一至三行就是利用 R 在處理向量計算的能力) 改寫為
pp <- prob[-1] - prob[-10]
就是將 prob 捨去第一個位置的值與捨去最後一個位置的值所得的兩個向量相減.
由於這種將一向量的值作'後'減'前'的計算,
在統計方法中是蠻常用到的一個功能, 在 R 中有個 diff() 的內設函數.
所以整個計算可再簡化為如下的一行即可:
pp <- diff(pexp(c(0, 9, 18, 27, 36, 45, 54, 63, 72, 200), 1/20))
當然, 先將資料存於 brck 的做法或應較好:
brck <- c(0, 9, 18, 27, 36, 45, 54, 63, 72, 200)
pp <- diff(pexp(brck, 1/20))
參考一下.
又, 順帶一提, 逗號後空一格, "<-" 的前後空一格, 以及程式的適當內縮,
都會讓程式較易閱讀, 也較能避免疏漏或錯誤, 當然也利於修改更正.
--
夫兵者不祥之器物或惡之故有道者不處君子居則貴左用兵則貴右兵者不祥之器非君子
之器不得已而用之恬淡為上勝而不美而美之者是樂殺人夫樂殺人者則不可得志於天下
矣吉事尚左凶事尚右偏將軍居左上將軍居右言以喪禮處之殺人之眾以哀悲泣之戰勝以
喪禮處之道常無名樸雖小天下莫能臣侯王若能守之萬物將自賓天地相合以降甘露民莫
之令而自均始制有名名亦既有夫亦將知止知止可以不殆譬道之在天下210.66.0.241海
推 DAVIDD0629:當初應該跟老師好好學的 囧 01/30 02:56
推 bcs:受教了,大謝 01/30 14:24
推 showfeb:用diff的指令,可以省去迴圈 02/27 00:29