16.1 简介
减少重复代码的方式一个是前面所提及的function功能一个是进行迭代计算
关于减少重复代码的好处我就不细谈了,书上已经写得非常清楚了。
- 明意图
- 便修改
- 少bug
本章将使用命令编程中的for循环和while循环对代码进行修改和提取。
for循环
for循环主要应用的索引
这个索引我认为就是位置,就跟目录页的书页号一样!
每个 for 循环都包括 3 个部分。
输出:output <- vector("double", length(x)) 这就是先给你输出的结果分配一个仓库,等一会结果出来了就直接怼进去!当然了仓库类型也不同 大小也不同。当然你也可以不指定仓库的类型。
序列:i in seq_along(df) 这就是有多少个要进行加工的货啊!
循环体 output[] <- median(df[])就是加工的过程是啥呀!出来的东西要进仓库了!
带着做一个练习题吧
Compute the mean of every column in mtcars
str(mtcars)
'data.frame': 32 obs. of 11 variables:
$ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
$ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
$ disp: num 160 160 108 258 360 ...
$ hp : num 110 110 93 110 175 105 245 62 95 123 ...
$ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
$ wt : num 2.62 2.88 2.32 3.21 3.44 ...
$ qsec: num 16.5 17 18.6 19.4 17 ...
$ vs : num 0 0 1 1 0 1 0 1 1 1 ...
$ am : num 1 1 1 0 0 0 0 0 0 0 ...
$ gear: num 4 4 4 3 3 3 3 4 4 4 ...
$ carb: num 4 4 1 1 2 1 4 2 2 4 ...
head(mtcars)
mpg cyl disp hp drat wt qsec
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02
Datsun 710 22.8 4 108 93 3.85 2.320 18.61
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02
Valiant 18.1 6 225 105 2.76 3.460 20.22
vs am gear carb
Mazda RX4 0 1 4 4
Mazda RX4 Wag 0 1 4 4
Datsun 710 1 1 4 1
Hornet 4 Drive 1 0 3 1
Hornet Sportabout 0 0 3 2
Valiant 1 0 3 1
output <- vector("double", ncol(mtcars))
names(output) <- names(mtcars)
for (i in names(mtcars)) {**这块要注意 如果你用seq_along返回的是带字符型数值的数据 不能计算哦!**
output[i] <- mean(mtcars[[i]])
}
output
#
for循环变体
修改现有对象(观测值)
df <- tibble(
a = rnorm(10),
b = rnorm(10),
c = rnorm(10),
d = rnorm(10)
)
rescale01 <- function(x) {
rng <- range(x, na.rm = TRUE)
(x - rng[1]) / (rng[2] - rng[1])
}
df$a <- rescale01(df$a)
df$b <- rescale01(df$b)
df$c <- rescale01(df$c)
df$d <- rescale01(df$d)
for (i in seq_along(df)) {
df[[i]] <- rescale01(df[[i]])
}
练习1中读取CSV文件 在批量提取测序数据的相同基因的表达值时用的到
df <- vector("list", length(files))
for (fname in seq_along(files)) {
df[[i]] <- read_csv(files[[i]])
}
df <- bind_rows(df)
for循环与函数式编程
重点说一下apply(),lapply(),tapply()等函数
- Apply Functions Over Array Margins Returns a vector or array or list of values obtained by applying a function to margins of an array or matrix.
apply(df,2,mean) #其中的2表示列 具体解释如下:给出将应用该函数的下标的向量。 例如,矩阵1表示行,2表示列,c(1,2)表示行和列。 其中X命名为dimnames,它可以是选择维名称的字符向量。
等价于
output <- vector("double", length(df))
for (i in seq_along(df)) {
output[i] <- mean(df[[i]])
}
output
- lapply返回一个与X相同长度的列表,其中每个元素都是将FUN应用于X的相应元素的结果。
> lapply(df, mean)
$`a`
[1] -0.4432281
$b
[1] -0.1124617
$c
[1] 0.2448539
$d
[1] -0.03413569
class(lapply(df,mean))
[1] "list"
- sapply是一个用户友好的版本和lapply的包装器,默认情况下通过应用
class(sapply(x, mean))
simplify2array()返回一个向量,矩阵,或者,如果需要,则更新一个数组(如果合适)。 sapply(x,f,simplify = FALSE,USE.NAMES = FALSE)与lapply(x,f)相同。
vapply类似于sapply,但具有预先指定类型的返回值,因此它可以更安全(有时更快)使用。
replicate是一个常用的sapply包装器,用于重复评估表达式(通常涉及随机数生成)。
simplify2array()是当simple不为false并且从mapply()类似地调用时从sapply()调用的实用程序。