——by不是杀杀
为了使我们写的代码更容易阅读、避免过段时间再看自己写的代码就头疼,我们在写代码的时候应该注意一些编码风格。大家可以选择一种自己喜欢的风格约束自己的代码,以下是来自Google的R语言编码风格。
命名
文件命名
以.R结尾,文件名最好能够一看就知道这个文件是用来做什么的
标识符命名
- 函数名首字母大写,且不用分隔符。函数名应为动词或动词性短语
- 参数首字母不大写,可以使用分隔符
- 常数命名规则和函数相同,但需要加上一个k开头,表明为常数
语法
缩进
不要混用制表符和空格。
当括号内进行换行时,下一行与括号内的第一个字符对齐
空白
- 在所有二元操作符(=,+,-,<-,等)的两侧加上空格
- 但在函数调用中传递参数时=两边的空格可以不加
- 逗号前面不加空格,逗号后面加空格
- 在(前加空格,函数调用时不用
- 不要在圆括号或方括号中的代码两侧加入空格
花括号
前括号永远不应该独占一行
后括号应当总是独占一行
代码块再短也要在新的一行开始写
如
# 不应该这样
if (is.null(ylim)) {ylim <- c(0, 0.06)}
# 应该写成这样
if (is.null(ylim)) {
ylim <- c(0, 0.06)
}
赋值
用 <- 进行赋值, 不用 = 赋值
分号
不用分号结束一行,也不要利用分号在同一行放多个命令
完全可以不使用分号
代码组织
总体布局和顺序
- 版权声明注释
- 作者信息注释
- 功能注释, 包括程序的用途, 输入和输出
- source() 和 library() 语句
- 函数
- 要执行的语句
单元测试应在另一个名为 原始的文件名_unittest.R 的独立文件中进行
注释
整行注释: # 后接一个空格开始
行内短注释:在代码后接两个空格, #, 再接一个空格
函数的定义和调用
先列出无默认值的参数, 然后再列出有默认值的参数
函数文档
函数在定义行下方都应当紧接一个注释区. 这些注释应当由如下内容组成:
此函数的一句话描述
此函数的参数列表, 用 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)
}
好了,看完这些基本的格式,现在让我立刻修改我之前写的一段混乱的代码
代码如下
library('optparse')
Round_ratio<- function(imputMat,Cutoff=0,Sat=1) # Sat:默认为1,几统计大于等于Sat的个数和小于Sat的个数
#Cutoff:若比值小于Cutoff则丢弃这个序列,默认为0 即默认关闭
{
## 去掉为0的序列
for(i in (3:ncol(imputMat))){
imputMat<- imputMat[-which(imputMat[,i]==0),]
if(Cutoff){
imputMat<- imputMat[-which(imputMat[,i]<Cutoff),]
if(dim(imputMat)[1]==0){print("Error: 删除存在小于阈值的序列后,剩余序列为0");return()}
}
}
Rratio <- imputMat[,1:2]
imputMat <- imputMat[,-c(1,2)] # 去掉一二列,即删除序列和total
Number_of_col<- dim(imputMat)[2] #计算出一共有几列
# RenameList <- matrix(NA,nrow=Number_of_colj,ncol=1)
for(i in 2:Number_of_col){
temp <- as.matrix(round(imputMat[,i]/imputMat[,(i-1)],2))
Rratio <- cbind(Rratio,temp)
Name <- paste(colnames(imputMat)[i],colnames(imputMat)[i-1],sep = "/") #生成列名
colnames(Rratio)[i+1] <- Name #重命名列
}
return(Rratio)
}
ratio_mat <- Round_ratio(result_seq,Cutoff)
write.table(ratio_mat,"比值结果.csv",quote = F,col.names = T,row.names = F,sep=',')
修改之后:
library('optparse')
Roundratio <- function (imputmat, cutoff=0, sat=1){
# 该函数用于计算每一轮序列的比值
#
# 参数:
# imputmat:输入文件,要求第一列为序列,第二列为总序列数,第三列开始为每轮序列数
# sat:几统计大于等于sat的个数和小于sat的个数,默认为1
# cutoff:若比值小于cutoff则丢弃这个序列,默认为0
#
# 返回:
# 该输入的每轮序列的比值
# 去掉为0的序列
for (i in (3 : ncol (imputmat))){
index <- which(imputmat[, i] == 0)
imputmat<- imputmat[-index, ]
if (cutoff){
index <- which(imputmat[, i] < cutoff)
imputmat<- imputmat[-index, ]
if (dim (imputmat)[1] == 0){
stop ("删除存在小于阈值的序列后,剩余序列为0")
}
}
}
roundratio_mat <- imputmat[, 1 : 2]
imputmat <- imputmat[, -c(1, 2)] # 去掉一二列,即删除序列和total
number_of_col <- dim (imputmat)[2] # 计算出一共有几列
for (i in 2 : number_of_col){
temp <- as.matrix (round (imputmat[, i] / imputmat[, (i - 1)], 2))
roundratio_mat <- cbind (roundratio_mat,temp)
new_colname <- paste (colnames (imputmat)[i], colnames (imputmat)[i - 1], sep="/") # 生成列名
colnames (roundratio_mat)[i + 1] <- new_colname # 重命名列
}
return (roundratio_mat)
}
ratio <- Roundratio(result_seq, cutoff)
write.table (ratio, "比值结果.csv", quote=F, col.names=T, row.names=F, sep=',')