1.准备工作
library(tidyverse)
#> ── Attaching packages ────────────────────────────────────────────────────────────────────── tidyverse 1.2.1 ──
#> ✔ ggplot2 3.0.0 ✔ purrr 0.2.5
#> ✔ tibble 1.4.2 ✔ dplyr 0.7.6
#> ✔ tidyr 0.8.1 ✔ stringr 1.3.1
#> ✔ readr 1.1.1 ✔ forcats 0.3.0
#> ── Conflicts ───────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
#> ✖ dplyr::filter() masks stats::filter()
#> ✖ dplyr::lag() masks stats::lag()
2.for循环
df <- tibble(
a = rnorm(10),
b = rnorm(10),
c = rnorm(10),
d = rnorm(10)
)
output <- vector("double", ncol(df))#1.输出
#建立了一个数据类型为双精度浮点数,长度等于df列数的向量
for (i in seq_along(df)) { # 2. 序列
output[[i]] <- median(df[[i]]) # 3. 循环体
}
output
#> [1] -0.36086007 0.45350996 0.35003826 0.08974874
第一次见vector,并不知道是干啥,探索过程(强大的内心戏):
#?vector,结果找到的是is.vctor和as.vector
#vector("double",1,2,3,4),报错
#vector("double",c(1,2,3,4)),报错
#恍然大悟后面的ncol意思是列数,不是列号,明明以#前是知道的,被自己蠢哭。
ncol(df)
#> [1] 4
#换成5试试,发现长度增加了1,所以这参数表示的是#向量长度。
x <- vector("double",5)
class(x)
#> [1] "numeric"
#double能换成啥?single?报错。
x <- vector("character",4)
x <- vector("integer",4)
#好的明白了,指定了数据类型嘛。
#并且我很纳闷为什么是[[]],用[]替换了一下发现output可以,后面的df[[]]报错。
复习到一个函数,seq_along,列出行号,笨办法是可以写成1:nrow(df)。
for循环的三个部分:输出、序列、循环体。
3.for循环的变体
3.1修改现有对象
将数据框中的每列都转换成0-1的大小,这个命题用dplyr做的思路是mutate或transmute。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])
}
#实现修改
for (i in seq_along(df)) {
df[[i]] <- rescale01(df[[i]])
}
书中给出了解释,for循环使用都[[]]。
3.2循环模式
循环模式:数值、元素、名称
results <- vector("list", length(x))
names(results) <- names(x)
小本本记下来,命名输出向量
x <- c(a=1,b=2,c=5)
results <- vector("list", length(x))
names(results) <- names(x)
#没看明白书上的代码,我改了一下试试
name <- vector("character",length(x))
value <- vector("double",length(x))
for (i in seq_along(x)) {
name[[i]] <- names(x)[[i]]
value[[i]] <- x[[i]]
}
name
#> [1] "a" "b" "c"
value
#> [1] 1 2 5
3.3未知长度的输出
means <- c(0, 1, 2)
output <- double()
for (i in seq_along(means)) {
n <- sample(100, 1) #抽样
output <- c(output,rnorm(n,means[[i]]))#向量延长
}
str(output)
#> num [1:82] -0.342 2.478 1.753 0.113 2.039 ...
#
out <- vector("list", length(means))
for (i in seq_along(means)) {
n <- sample(100, 1)
out[[i]] <- rnorm(n, means[[i]])
}
str(out)
#> List of 3
#> $ : num [1:31] 0.61 0.474 -1.643 -0.702 -0.708 ...
#> $ : num [1:22] -1.125 -0.265 0.491 1.348 -0.39 ...
#> $ : num [1:42] 1.768 3.002 1.132 1.588 0.122 ...
str(unlist(out))
#> num [1:95] 0.61 0.474 -1.643 -0.702 -0.708 ...
3.4未知的序列长度-while循环
while (condition) {
/# 循环体
}
for (i in seq_along(x)) {
/# 循环体
}
等价于
i <- 1
while (i <= length(x)) {
/# 循环体
i <- i + 1
}
一个简单的while循环:
flip <- function() sample(c("T", "H"), 1)
flips <- 0
nheads <- 0
while (nheads < 3) {
if (flip() == "H") {
nheads <- nheads + 1
} else {
nheads <- 0
}
flips <- flips + 1
}
flips
#> [1] 10
#> [1] 3
啊啊啊,无心继续学习,只想清空购物车,今天去苹果专卖店摸了摸新出的卖布Air,已经向饲养员申请到了¥¥¥!开心
另外,2018.11.14是豆豆和花花恋爱六周年,有一波狗粮在路上了,不吃记得绕路!
网友评论