1. 程式人生 > >如何寫出整潔規範的R程式碼?是時候討論一下程式碼規範性了

如何寫出整潔規範的R程式碼?是時候討論一下程式碼規範性了

在雙11免費Get新知識的人,才是最會花錢的人,也將是最會賺錢的人!

別的專場拼消費,唯有天善學院,投資你的未來!

640?wx_fmt=png

點選圖片,檢視課程詳情

作者魯偉熱愛資料,堅信資料技術和程式碼改變世界。R語言和Python的忠實擁躉,為成為一名未來的資料科學家而奮鬥終生。

個人公眾號:機器學習實驗室 (微信ID:louwill12)


接觸 R 語言快兩年時間了,多少也算是對 R 有了個囫圇瞭解,平日裡沒事愛倒騰個數據來分析一下,期間自然踩過不少坑,有些還是深坑巨壑。兩年來 R 基礎這塊的報錯基本見了個遍,所以每當有新手小白問我問題幫他們解決後就一口一個大神大佬大咖的,唬得我全身不自在。等到人都散去,坐到電腦邊開啟 R 語言,深感恐懼,於是奮而用心學習。之前少年志氣,不知天高地厚,而今對資料科學越發深入學習,越感自己積貧積弱。貌似扯歪了,下面言歸正傳。


建了公眾號之後時常會有學習 R 語言的朋友要求加我微信,同意好友申請之後咣噹一個檔案扔過來然後說了句讓我幫他看看程式碼哪裡不對,懷著萬分複雜的心情打開了他的程式碼檔案,各種亂碼無註釋中英文標點混用讓我瞬間抓狂,看完也導致情緒不穩定了。沒註釋其實還可以理解,畢竟大家都懶,小編也經常在寫程式碼的時候放飛自我不加任何註釋,但這樣的程式碼我是不敢給別人看的。但是很多同學在寫 R 程式碼時也忒不認真了,中英文標點和括號混用的風生水起還一個勁的問我程式碼怎麼可能錯。小編在此之前雖然對程式碼規範性不加重視,但也不敢如此造次。今天小編就跟大家認真談論一下怎樣才能寫出規範整潔的 R 語言程式碼。


註釋

註釋是一門程式語言的基本要素,更是 R 語言使用者的自我修養。抱著對自己程式碼負責任的態度,養成良好的註釋習慣,對你自己和對大家都有好處。至於怎麼寫註釋,如何把 R 註釋寫得清新脫俗那就需要一番講究了,一般的 R 程式碼中註釋包括檔案註釋、程式碼塊的註釋以及具體重要單行程式碼的註釋。


檔案註釋比較正式,像小編這麼不正式的人自個兒玩的時候從來不寫檔案註釋,所謂檔案註釋,就是要在你這個檔案程式碼開始前需要宣告的一些內容,比如說什麼環境下執行本程式碼、使用哪個版本的 RStudio、約定編碼方式(通常是 utf-8)以及這個程式碼檔案主要是用來幹嘛的。通常檔案註釋開始可以用兩個#。

檔案註釋

## !/user/bin/env RStudio 1.0153
## -*- coding: utf-8 -*-
## exploratory data analysis of nba shooting data


程式碼塊註釋顧名思義就是對某個程式碼塊的一個註釋,在 R 中為了提高程式碼效率,我們通常喜歡把函式模組化以避免程式碼大面積重複,這時候來一行程式碼塊註釋可能會更搭配。程式碼塊註釋通常也是使用兩個#。

程式碼塊註釋

## define MyStyle function for ggplot2.boxplot
MyStyle <- function(xName, yName, groupName){
 ggplot2.boxplot(data = doc, xName, yName, groupName,
                 showLegend = FALSE, na.rm = TRUE)
}
boxplot1 <- MyStyle('team_expert', 'reservations', 'team_expert') +
           scale_fill_brewer(palette = "Paired")


最後是單行程式碼註釋,也可以叫短註釋,通常放在一行程式碼的後面,在程式碼較長時也可以另起一行進行註釋,但要儘量保證每行程式碼要對齊,不然程式碼加註釋混一起亂糟糟的一團很影響心情。


命名規範

與註釋一樣, R語言中規範地對程式碼中的變數、函式和檔名進行命名也是一項 R 語言使用者的基本操守。我知道身邊大夥都很隨性,字裡行間通常筆走龍蛇不拘一格,但到了 R 語言這裡,還是麻煩大夥兒規規矩矩的來。對 R 檔案的命名應儘可能以體現檔案內容為準,比如說這個檔案程式碼是用來分析 NBA 球員投籃資料的,那麼檔案可以命名為 analysis_nba_data.R,千萬不要信馬由繮隨便命名,日後坑的都是你自己。


函式和變數的命名則需要尤其小心,在 R 環境對於大小寫是極其敏感的,變數名應該都使用小寫字母,而函式名則可以在首字母使用大寫,另一點需要注意的是變數和函式命名時應儘量避免與 R 環境中本身存在的一些函式或者變數重名,不然系統也會混亂弄不清的。不同單詞間可以用 . 或者 _ 來連線,看個人習慣,但貌似谷歌的 R語言程式碼規範上要求使用 . 來連線。而命名函式則儘量不要使用下劃線或者點連線符,在單詞選擇上也最好能體現函式的動作,以動詞來命名函式。且看下面例子:

變數

正例: shooting_distance   shooting.distance

反例: ShootingDistance  

函式

正例: GetShootingEff  

反例: getshootingeff


程式碼組織

有組織有層次的 R 程式碼通常會出現在正式的專案中,其實在程式碼組織上我覺得Python就做的非常好,時常去 GitHub 上觀摩一番別人的程式碼感覺也是賞心悅目。在正式的 R 語言專案裡,以下內容是必不可少的:

  • 版權宣告

  • 編碼和環境宣告

  • 作者註釋

  • 檔案說明

  • 專案目的

  • 輸入與輸出說明

  • 函式定義說明

  • 其他


在日常的 R 程式碼訓練時,這些就有點過於苛求了。像小編這麼懶的人連個編碼都懶得宣告一下的,還是平時多養成多宣告的習慣的好,不然等著正式接專案了必定手足無措漏洞百出。


R 程式設計的一般約定

除了上述我們不能違背的一些較為明顯的規定之外,在 R 中通常還包括一些約定俗成的規則,小編在之前的學習中就不大注意這些規矩,以致於寫的程式碼被內行人一眼看上去就知道是很業餘的 code 。那這些約定俗成的規定具體包括哪些呢?小編去認真查找了一下 Google 的 R 程式碼規範手冊,且看慢慢道來。

1. 每行程式碼最長不超過 80 個字元

合理,一行程式碼過程效率既低又不美觀。

2. 使用空格鍵空兩格進行縮排,儘量不要用 Tab 鍵

實際測試了下,感覺差不多。但可能是我沒發現其中奧妙。

3. 使用 <- 符號進行賦值,而不是 = 號。使用 <- 符號進行賦值,而不是 = 號。使用 <- 符號進行賦值,而不是 = 號。(重要的事情說三遍!不要跟我說二者沒差別啊什麼的,函式內參數指定除外)

4. 在使用二次運算子時(+ - = <-)兩端都需要空一格。

非常簡單的建議,保證程式碼不擠在一起一團糟。

5. 逗號。逗號前不用空格,但逗號後一定要空一格。同第 4 條,很實用的建議。

6. 分號。無特殊情況不要使用分號。

7. 花括號。通常在迴圈語句或者自定義函式中需要用到。左花括號不換行寫,右花括號獨佔一行寫。

8. 儘量少用 attach 函式。我喜歡稱之為繫結函式。這一點還不能體會很深,我用到現在還沒出現過大問題,可能是 R 環境中綁來綁去容易把變數弄混吧。

9. 小括號。在前括號前加一個空格,但呼叫函式時除外,特指 if 等迴圈命令。

10. 全部程式碼約定應保持一致。不能一會兒有空格一會兒又擠在一起,當然我們要求是全部有空格。


正例

#自定義函式對ggplot.box進行封裝
MyStyle <- function(xName, yName, groupName){
 ggplot2.boxplot(data = doc, xName, yName, groupName,
                 showLegend = FALSE, na.rm = TRUE)
}      

反例

MyStyle<-function(xName,yName,groupName){
ggplot2.boxplot(data=doc,xName,yName,groupName,
showLegend=FALSE,na.rm=TRUE)}    


測試效率並優化程式碼

實際上這部分並不屬於 R 程式碼規範的必備內容。但還是有必要強調一下。無論新手老手,都不可能把程式寫的完美無缺,當你寫完一段程式碼之後,你需要測試這段程式碼的效率並對其進行不斷的優化。RGui 中沒有測試程式碼的工具,但 RStudio 完美的解決了這一問題,在用 Debug 檢測完你的程式碼正確與否之後,你還可以使用 Profile來檢測你的程式碼效率如何,這一點無論是對 R 新手使用者還是老使用者都不容易。


常用的優化程式碼效率的方式包括函式模組化、向量化運算以及多使用 R 內建函式。前兩天在在網上找到謝益輝老大的一個報告,主題叫做論 R 使用者的自我修養,其中的一個要點就是函式模組化。通常在重複呼叫一些含有較多引數的函式時,我們的程式碼會看起來很臃腫,一眼看去就有很多冗餘。比如 ggplot 函式通常會包括眾多引數,我們在重複呼叫時可以自定義一個呼叫函式,將我們想利用的圖形格式引數都模組化到自定義函式模組中去,這樣會大大提升程式碼效率。


少用迴圈而多用 R 自帶的向量化運算。自打入坑以來就曾被人告誡 R 的迴圈效率極低,能不用則不用。前段時間曾寫了個關於 apply 函式族的用法心得,R 語言向量化運算精髓即在於此,有興趣的同學可以自行去翻看。最後一點則是要儘可能地利用 R 中已經封裝好了的函式,不要求個平均值還要自己去編個迴圈,其實一個 mean 函式就可以搞定。重複造輪子的事情在目前情況下儘量少做吧,一句話,都是為了效率。


參考資料:

Google 的R 語言程式碼規範


END    



今日

爆款

Python3網路爬蟲實戰案例
4折優惠等著你 掃描 下圖二維碼 即可學習 點選 閱讀原文 加入SVIP可免費學習


640?wx_fmt=png