搜索
查看: 521|回复: 0

[R] 小洁详解《R数据科学》--第十六章 purrr(上)

[复制链接]

25

主题

49

帖子

363

积分

中级会员

Rank: 3Rank: 3

积分
363
发表于 2018-12-10 10:43:38 | 显示全部楼层 |阅读模式
本帖最后由 hijack 于 2018-11-26 14:14 编辑

1.准备工作
[AppleScript] 纯文本查看 复制代码
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循环
[AppleScript] 纯文本查看 复制代码
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,并不知道是干啥,探索过程(强大的内心戏):
[AppleScript] 纯文本查看 复制代码
#?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循环的方法更加简单直接。
[AppleScript] 纯文本查看 复制代码
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)
小本本记下来,命名输出向量
[AppleScript] 纯文本查看 复制代码
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未知长度的输出
[AppleScript] 纯文本查看 复制代码
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 ...
#

[AppleScript] 纯文本查看 复制代码
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循环:
[AppleScript] 纯文本查看 复制代码
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

生信技能树公益视频合辑:学习顺序是linux,r,软件安装,geo,小技巧,ngs组学!
B站链接:https://m.bilibili.com/space/338686099
YouTube链接:https://m.youtube.com/channel/UC67sImqK7V8tSWHMG8azIVA/playlists
生信工程师入门最佳指南:https://mp.weixin.qq.com/s/vaX4ttaLIa19MefD86WfUA
学徒培养:https://mp.weixin.qq.com/s/3jw3_PgZXYd7FomxEMxFmw
资料大全:https://mp.weixin.qq.com/s/QcES9u1vYh-l6LMXPgJIlA
[size=0em]​




上一篇:小洁详解《R数据科学》--第十五章 向量(下)
下一篇:小洁详解《R数据科学》第16章 Purrr下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|生信技能树 ( 粤ICP备15016384号  

GMT+8, 2019-8-24 22:37 , Processed in 0.037106 second(s), 26 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.