【上一篇:79.关于Augmented vectors】
【下一篇:81.关于Base R中的for循环】
减少代码重复的三个优点:
1. 更容易看出代码的意图:因为人们总是最关注到不同的点,而不是千篇一律的地方
2. 更容易响应修改的需求:当需要修改代码时,你只需修改一个地方即可,而不是你复制-粘贴的所有地方
3. 减少Bugs数:因为一行代码可以在多处使用。
减少代码重复的两个工具:1)function:提取重复模式的代码并将其独立存放,便于重复使用和更新;2)iteration:当需要对多个输入做相同的事情时,比如在不同的列或不同的数据集上重复相同的操作。
两个重要的iteration范例:1)imperative programing(命令行式编程):for循环和while循环工具,好处是可以从代码中很明显地看到什么正在发生,缺点是语句略显啰嗦,对每个for loop,都有一些bookkeeping式的重复代码,可对学习iteration不失为一个很好的开始;2)functional programing(FP):提供一种工具,可以将重复代码提取出来,这样每一种共同的for loop都可以有自己的函数。
比如:你编写了一个Mean函数用来求一个向量的平均值,你的需求是求一个data frame中每一列的平均值。不使用for循环的时候你是这样写的:
# 自定义函数
Mean <- function(x){
mean_value <- sum(x,na.rm=T)/length(x)
return(mean_value)
}
# 输入数据
df <- data.frame(
a=rnorm(10),
b=rnorm(10),
c=rnorm(10),
d=rnorm(10)
)
# 求df中每一列的平均值(不用for循环)
Mean(df$a)
Mean(df$b)
Mean(df$c)
Mean(df$d)
# 求df中每一列的平均值(使用for循环)
output <- vector("double",length=length(df))
for(i in seq_along(df)){
output[[i]] <- Mean(df[[i]])
}
output
# 如果是不同的数据集,你可以将上一步中的for循环搞成一个函数
df_mean <- function(df){
output <- vector("double",length=length(df))
for(i in seq_along(df)){
output[[i]] <- Mean(df[[i]])
}
return(output)
}
df1 <- df
df2 <- df
# 对每个数据集,求每列的平均值
for(j in c(df,df1,df2)){
result <- df_mean(j)
print(result)
}
vector()和seq_along()函数
vector()函数产生一个给定长度和mode的向量(向量当然包括atomic vector和List啦!)。
# 参数说明
vector(mode = "logical", length = 0)
mode:字符串,atomic vector mode或list、expression。
length:非负值(可以是0)指定期望的长度,如果length>.Machine$integer.max(2147483647)时,mode必须是"double"
atomic vector mode包括:"logical", "integer", "numeric" (synonym "double"), "complex", "character" 和"raw"。
对mode=logical,vector元素初始化为FALSE
对mode=numeric,vector元素初始化为0
对mode=character,vector元素初始化为""
对mode=raw,vector元素初始化为nul bytes
对mode=list/expression,vector元素初始化为NULL
seq_along()函数从给定参数的长度中生成一个integer vector(除非长度>.Machine$integer.max)。
seq_along(along.with)
along.with可以是atomic vector,list,data frame等
> seq_along(df)
[1] 1 2 3 4
seq_along(df)比1:length(df)好,因为当df的长度为0时,seq_along()可以得到正确的结果:integer(0),而1:length(f)的结果是1:0。用seq_along()可以避免不经意间使用长度为0的对象导致的错误。
网友评论