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()調用的實用程序。