《R语言初学指南》一2.3 找到R脚本中的错误
本節(jié)書(shū)摘來(lái)自異步社區(qū)《R語(yǔ)言初學(xué)指南》一書(shū)中的第2章,第2.3節(jié),作者【美】Brian Dennis(布萊恩·丹尼斯),更多章節(jié)內(nèi)容可以訪問(wèn)云棲社區(qū)“異步社區(qū)”公眾號(hào)查看
2.3 找到R腳本中的錯(cuò)誤
R語(yǔ)言初學(xué)指南
復(fù)雜項(xiàng)目中的R腳本會(huì)非常長(zhǎng)。即使是R專(zhuān)家,也很少能一次性將其編寫(xiě)正確。腳本中的所有錯(cuò)誤都是通過(guò)調(diào)試來(lái)修改的。
在腳本中稱(chēng)追蹤錯(cuò)誤或“bug”為“調(diào)試”。調(diào)試包括一些適用性檢測(cè)工作。
下面在腳本中故意制造一個(gè)bug,由此來(lái)練習(xí)如何調(diào)試。首先來(lái)做一些清理工作。使控制臺(tái)成為活動(dòng)窗口,并輸入下列命令:
>objects()按照慣例,這里在展示控制臺(tái)中的命令時(shí),依然在其前面顯示R提示符(“>”),但要記住,在控制臺(tái)中不需要輸入該提示符。不要忘記命令末尾的括號(hào)。在運(yùn)行該命令后,就可在工作區(qū)內(nèi)看到一串已用R命令建立好的“對(duì)象”:
[1] "a" "b" "k" "kill.rate" [5] "m" "moose.density"這些對(duì)象已存儲(chǔ)在R中,可供日后調(diào)用。現(xiàn)在輸入下列命令:
>rm(a,b,k,kill.rate,m,moose.density) >a哎?找不到對(duì)象a了,其他幾個(gè)對(duì)象也找不到。命令rm()表示“移除”,它會(huì)刪除括號(hào)中的所有對(duì)象。由于用戶(hù)可能會(huì)忘記之前在R會(huì)話中建立的對(duì)象,而導(dǎo)致后面的計(jì)算出現(xiàn)錯(cuò)誤,這時(shí)命令objects()和rm()就會(huì)非常有用。
現(xiàn)在開(kāi)始通過(guò)制造bug來(lái)搞破壞!回到R編輯器中,將腳本的第一個(gè)命令moose.density的首字母改為大寫(xiě)字母M,然后重新運(yùn)行腳本。這時(shí)會(huì)彈出圖形窗口,但其中沒(méi)有圖形顯示——出現(xiàn)錯(cuò)誤了。看一下控制臺(tái),找到與下列語(yǔ)句相似的內(nèi)容(在不同版本的R中,出現(xiàn)的錯(cuò)誤信息可能會(huì)稍有不同):
> Moose.density=c(.17,.23,.23,.26,.37,.42,.66,.80,1.11,1.30,1.37, + 1.41,1.73,2.49) > kill.rate=c(.37,.47,1.90,2.04,1.12,1.74,2.78,1.85,1.88,1.96, + 1.80,2.44,2.81,3.75) > plot(moose.density,kill.rate,type="p") Error in plot(moose.density, kill.rate, type = "p") :object 'moose.density' not found > m=2.5*(0:100)/100 > a=3.37 > b=0.47 > k=a*m/(b+m) > points(m,k,type="l") Error in plot.xy(xy.coords(x, y), type = type, ...) :plot.new has not been called yet控制臺(tái)中重現(xiàn)了腳本,其中還包含兩條錯(cuò)誤信息。這里有兩點(diǎn)非常重要,需要注意。
首先,盡管沒(méi)有修改plot()語(yǔ)句和points()語(yǔ)句,但它們下面出現(xiàn)了錯(cuò)誤信息,而實(shí)際上有錯(cuò)誤(大寫(xiě)字母M)的語(yǔ)句卻沒(méi)有任何提示。在腳本中,錯(cuò)誤可以影響下面一系列命令出錯(cuò)。這里,定義向量Moose.density的命令是一個(gè)在R中完全正確的語(yǔ)句,它在R的內(nèi)存中建立了對(duì)象Moose.density以便日后調(diào)用,在控制臺(tái)中使用object()命令即可看到這一對(duì)象。問(wèn)題出在繪圖語(yǔ)句上。plot()語(yǔ)句使用的向量moose.density并不存在,故plot()語(yǔ)句無(wú)法進(jìn)行繪圖。接著由于沒(méi)有元素可以添加到圖形中,points()語(yǔ)句也就無(wú)法執(zhí)行。
其次,在通常情況下,若可以定位并修正某個(gè)錯(cuò)誤,則后面的一些錯(cuò)誤也會(huì)被修正。因此,建議用戶(hù)在策略上,要從上到下一個(gè)一個(gè)地修改錯(cuò)誤。此外,在每修改完一個(gè)語(yǔ)句或一小部分R腳本后,就對(duì)它們進(jìn)行測(cè)試,以防修改本身包含錯(cuò)誤并對(duì)后續(xù)的語(yǔ)句產(chǎn)生影響。不過(guò),即使再小心謹(jǐn)慎,也幾乎沒(méi)有很長(zhǎng)的R腳本可在第一次就能完美地運(yùn)行出來(lái)。
若要在腳本中檢測(cè)并定位不明顯的錯(cuò)誤,需要對(duì)腳本從頭開(kāi)始進(jìn)行一系列搜索及實(shí)驗(yàn)。在空白的工作區(qū)中,可選中代碼并運(yùn)行這部分腳本,從而很方便地完成這一任務(wù)。讀者可以試一下:首先像剛才一樣,在控制臺(tái)中刪除工作區(qū)內(nèi)的所有對(duì)象,然后在R編輯器中選中第一個(gè)命令,使其高亮。在“Edit”的下拉菜單中(在微軟的Windows中,若對(duì)高亮區(qū)點(diǎn)擊右鍵,會(huì)彈出菜單),找到并點(diǎn)擊“Run line selection”選項(xiàng),即可運(yùn)行腳本中的第一行命令。在控制臺(tái)中檢查一下,這條命令建立了哪些對(duì)象。
若該命令的運(yùn)行情況與預(yù)期一致,則繼續(xù)運(yùn)行下一條語(yǔ)句。單獨(dú)選中并運(yùn)行下一條語(yǔ)句,然后再連同腳本中前面的語(yǔ)句一起運(yùn)行一遍。
當(dāng)檢查到繪圖語(yǔ)句時(shí),錯(cuò)誤信息就會(huì)出現(xiàn)。繪圖命令在尋找一個(gè)不存在的對(duì)象。若在之前的檢查中沒(méi)有發(fā)現(xiàn)Moose.density與moose.density是兩個(gè)不同的對(duì)象,這時(shí)也許能清晰地發(fā)現(xiàn)這一點(diǎn)。R的用戶(hù)應(yīng)當(dāng)時(shí)刻注意變量名的大小寫(xiě)以及拼寫(xiě)錯(cuò)誤問(wèn)題,這是錯(cuò)誤的一個(gè)主要來(lái)源。
找到并改正大寫(xiě)的M,然后運(yùn)行腳本,即可成功繪圖。但是等一下:過(guò)早地認(rèn)為這是一個(gè)完美的腳本可能會(huì)導(dǎo)致失敗。有時(shí)即使腳本可以很好地運(yùn)行,其運(yùn)行結(jié)果也可能錯(cuò)得離譜。當(dāng)計(jì)算本身有概念性的錯(cuò)誤時(shí),這種情況就會(huì)發(fā)生。R會(huì)精確完成用戶(hù)的指令,且當(dāng)用戶(hù)的指令有錯(cuò)誤時(shí),R也會(huì)按錯(cuò)誤指令忠實(shí)地運(yùn)行完成。
數(shù)據(jù)輸入是否正確?作者在輸入本章數(shù)據(jù)時(shí),是否與第1章保持一致了呢?要想有效地使用R,仔細(xì)一點(diǎn)兒總不會(huì)錯(cuò)。
總結(jié)
以上是生活随笔為你收集整理的《R语言初学指南》一2.3 找到R脚本中的错误的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【ASM 翻译系列第二弹:ASM 12C
- 下一篇: 《深入理解Spark:核心思想与源码分析