Doctor Cheung
來自 Google 的 R 語言編碼風格指南
R 語言是一門主要用於統計計算和繪圖的高階程式語言. 這份 R 語言編碼風格指南旨在讓我們的 R 程式碼更容易閱讀、分享和檢查. 以下規則系與 Google 的 R 使用者群體協同設計而成.
表示和命名
檔案命名
檔名應以 .R (大寫) 結尾, 檔名本身要有意義.
正例: predict_ad_revenue.R
反例: foo.R
識別符號命名
在識別符號中不要使用下劃線 ( _ ) 或連字元 ( - ). 識別符號應根據如下慣例命名. 變數名應使用點 (.) 分隔所有的小寫字母或單詞; 函式名首字母大寫, 不用點分隔 (所含單詞首字母大寫); 常數命名規則同函式, 但需使用一個 k 開頭.
variable.name
正例: avg.clicks
反例: avg_Clicks , avgClicks
FunctionName
正例: CalculateAvgClicks
反例: calculate_avg_clicks , calculateAvgClicks
函式命名應為動詞或動詞性短語.
例外: 當建立一個含類 (class) 屬性的物件時, 函式名 (也是constructor) 和類名 (class) 應當匹配 (例如, lm).
kConstantName
語法
單行長度
最大單行長度為 80 個字元.
縮排
使用兩個空格來縮排程式碼. 永遠不要使用製表符或混合使用二者.
例外: 當括號內發生折行時, 所折行與括號內的第一個字元對齊.
空白
在所有二元操作符 (=, +, -, <-, 等等) 的兩側加上空格.
例外: 在函式呼叫中傳遞引數時 = 兩邊的空格可加可不加.
不可在逗號前加空格, 逗號後總須加空格.
正例:
tabPrior <- table(df[df$daysFromOpt < 0, “campaignid”])
total <- sum(x[, 1])
total <- sum(x[1, ])
反例:
tabPrior <- table(df[dfdaysFromOpt<0, “campaignid”]) # 在 ‘<’ 兩側需要增加空格
tabPrior <- table(df[df
tabPrior<- table(df[dfdaysFromOpt < 0, “campaignid”]) # 在 <- 前需要一個空格
tabPrior<-table(df[dfdaysFromOpt < 0, “campaignid”]) # 在 <- 兩側需要增加空格
total <- sum(x[,1]) # 逗號後需要一個空格
total <- sum(x[ ,1]) # 逗號後需要一個空格, 而非逗號之前
在前括號前加一個空格, 函式呼叫時除外.
正例:
if (debug)
反例:
if(debug)
多加空格 (即, 在行內使用多於一個空格) 也是可以的, 如果這樣做能夠改善等號或箭頭 (<-) 的對齊效果.
plot(x = xCoord,
y = dataMat[, makeColName(metric, ptiles[1], “roiOpt”)],
ylim = ylim,
xlab = “dates”,
ylab = metric,
main = (paste(metric, ” for 3 samples “, sep=”“)))
不要向圓括號或方括號中的程式碼兩側加入空格.
例外: 逗號後總須加空格.
正例:
if (debug)
x[1, ]
反例:
if ( debug ) # debug 的兩邊不要加空格
x[1,] # 需要在逗號後加一個空格
花括號
前括號永遠不應該獨佔一行; 後括號應當總是獨佔一行. 您可以在程式碼塊只含單個語句時省略花括號; 但在處理這類單個語句時, 您必須 前後一致地 要麼全部使用花括號, 或者全部不用花括號.
if (is.null(ylim)) {
ylim <- c(0, 0.06)
}或 (不可混用)
if (is.null(ylim))
ylim <- c(0, 0.06)總在新起的一行開始書寫程式碼塊的主體.
反例:
if (is.null(ylim)) ylim <- c(0, 0.06)
if (is.null(ylim)) {ylim <- c(0, 0.06)}
賦值
使用 <- 進行賦值, 不用 = 賦值.
正例:
x <- 5
反例:
x = 5
分號
不要以分號結束一行, 也不要利用分號在同一行放多於一個命令. (分號是毫無必要的, 並且為了與其他Google編碼風格指南保持一致, 此處同樣略去.)
程式碼組織
總體佈局和順序
如果所有人都以相同順序安排程式碼內容, 我們就可以更加輕鬆快速地閱讀並理解他人的指令碼了.
註釋準則
註釋您的程式碼. 整行註釋應以 # 後接一個空格開始.
行內短註釋應在程式碼後接兩個空格, #, 再接一個空格.
# Create histogram of frequency of campaigns by pct budget spent.
hist(df$pctSpent,
breaks = “scott”, # method for choosing number of buckets
main = “Histogram: fraction budget spent by campaignid”,
xlab = “Fraction of budget spent”,
ylab = “Frequency (count of campaignids)”)
函式的定義和呼叫
函式定義應首先列出無預設值的引數, 然後再列出有預設值的引數.
函式定義和函式呼叫中, 允許每行寫多個引數; 折行只允許在賦值語句外進行.
正例:
PredictCTR <- function(query, property, numDays,
showPlot = TRUE)
反例:
PredictCTR <- function(query, property, numDays, showPlot =
TRUE)
理想情況下, 單元測試應該充當函式呼叫的樣例 (對於包中的程式來說).
函式文件
函式在定義行下方都應當緊接一個註釋區. 這些註釋應當由如下內容組成: 此函式的一句話描述; 此函式的引數列表, 用 Args: 表示, 對每個引數的描述 (包括資料型別); 以及對於返回值的描述, 以 Returns: 表示. 這些註釋應當描述得足夠充分, 這樣呼叫者無須閱讀函式中的任何程式碼即可使用此函式.
示例函式
> CalculateSampleCovariance <- function(x, y, verbose = TRUE) { #
> Computes the sample covariance between two vectors. # # Args: #
> x: One of two vectors whose sample covariance is to be calculated. #
> y: The other vector. x and y must have the same length, greater than
> one, # with no missing values. # verbose: If TRUE, prints
> sample covariance; if not, not. Default is TRUE. # # Returns: #
> The sample covariance between x and y. n <- length(x) # Error
> handling if (n <= 1 || n != length(y)) {
> stop("Arguments x and y have invalid lengths: ",
> length(x), " and ", length(y), ".") } if (TRUE %in% is.na(x) || TRUE %in% is.na(y)) {
> stop(" Arguments x and y must not have missing values.") } covariance <- var(x, y) if (verbose)
> cat("Covariance = ", round(covariance, 4), ".\n", sep = "") return(covariance) }
TODO 書寫風格
編碼時通篇使用一種一致的風格來書寫 TODO.
TODO(您的使用者名稱): 所要採取行動的明確描述
語言
Attach
使用 attach 造成錯誤的可能數不勝數. 避免使用它.
函式
錯誤 (error) 應當使用 stop() 丟擲.
物件和方法
S 語言中有兩套面向物件系統, S3 和 S4, 在 R 中這兩套均可使用. S3 方法的可互動性更強, 更加靈活, 反之, S4 方法更加正式和嚴格. (對這兩套系統的說明, 參見 Thomas Lumley 的文章 “Programmer’s Niche: A Simple Class, in S3 and S4”, 發表於 R News 4/1, 2004, 33 - 36 頁: http://cran.r-project.org/doc/Rnews/Rnews_2004-1.pdf.)
這裡推薦使用 S3 物件和方法, 除非您有很強烈的理由去使用 S4 物件和方法. 使用 S4 物件的一個主要理由是在 C++ 程式碼中直接使用物件. 使用一個 S4 泛型/方法的主要理由是對雙引數的分發.
避免混用 S3 和 S4: S4 方法會忽略 S3 中的繼承, 反之亦然.
例外
除非有不去這樣做的好理由, 否則應當遵循以上描述的編碼慣例. 例外包括遺留程式碼的維護和對第三方程式碼的修改.
結語
遵守常識, 前後一致.
如果您在編輯現有程式碼, 花幾分鐘看看程式碼的上下文並弄清它的風格. 如果其他人在 if 語句周圍使用了空格, 那您也應該這樣做. 如果他們的註釋是用星號組成的小盒子圍起來的, 那您也要這樣寫。
遵循編碼風格準則的意義在於, 人們相當於有了一個程式設計的通用詞彙表, 於是人們可以專注於您在 說什麼, 而不是您是 怎麼說 的. 我們在這裡提供全域性的編碼風格規則以便人們瞭解這些詞彙, 但區域性風格也很重要. 如果您加入檔案中的程式碼看起來和周圍的已有程式碼截然不同, 那麼程式碼閱讀者的閱讀節奏就會被破壞. 儘量避免這樣做. OK, 關於如何寫程式碼已經寫得夠多了; 程式碼本身要有趣的多. 編碼愉快!