R数据科学(R for Data Science)

Part 3:编程


转换——可视化——模型

--------------第13章 使用magrittr进行管道操作--------------------

  1. library(tidyverse)
  2. #管道不能支持以下函数:
  3. #①使用当前环境的函数:如assign/get/load
  4. assign("x",10)
  5. x
  6. "x" %>% assign(100) # 这里的赋值是由%>% 建立的临时环境进行的
  7. env <- environment()
  8. "x" %>% assign(100,envir = env) #指定环境实现赋值
  9. #②惰性求值的函数:如tryCatch(捕获并处理程序错误)/try/suppresMessages/suppressWarnings
  10. tryCatch(stop("!"),error=function(e)"an error")
  11. stop("!") %>% tryCatch(error=function(e)"an error")
  12. #管道不适用情形:
  13. #操作步骤太多,如10个以上
  14. #有多个输入输出
  15. #步骤有复杂依赖关系

-----------------第14章 函数-------------------------------------

  1. #一段代码复制粘贴超过2次,就应该考虑写一个函数
  2. #创建一个函数名称
  3. #列出函数输入,即参数
  4. #将已经编好的代码放在函数体中
  5. #简单输入测试
  6. rescale01 <- function(x){
  7. rng <- range(x,na.rm = T,finite=T)
  8. (x-rng[1])/(rng[2]-rng[1])
  9. }
  10. rescale01(c(1,2,3.4,NA))
  11. #函数名最好是动词,参数一般是名词
  12. ?`if` #获取if帮助
  13. #if条件操作符组合 || && ,不同于向量化操作符| &
  14. #常用条件:== all() any() identical()
  15. identical(0L,0) #很严格,类型需一致
  16. x <- sqrt(2)^2
  17. x==2
  18. x-2
  19. dplyr::near(x,2)
  20. #多重条件:
  21. # if()else if()else
  22. # switch()
  23. #参数两类:数据;细节
  24. #使用近似正态分布计算均值两端的置信区间
  25. mean_ci <- function(x,conf = 0.95){
  26. se <- sd(x) / sqrt(length(x))
  27. alpha <- 1-conf
  28. mean(x)+se*qnorm(c(alpha/2,1-alpha/2))
  29. }
  30. x <- runif(100)
  31. mean_ci(x)
  32. mean_ci(x,conf = 0.99)
  33. #检查参数:stop函数
  34. wt_mean <- function(x,w){
  35. if(length(x)!=length(w)){
  36. stop("`x` and `w` must be the same length",call. = F)
  37. }
  38. sum(w*x)/sum(x)
  39. }
  40. #内置函数:stopifnot
  41. wt_mean <- function(x, w, na.rm = FALSE){
  42. stopifnot(is.logical(na.rm),length(na.rm) == 1)
  43. stopifnot(length(x) == length(w))
  44. if(na.rm){
  45. miss <- is.na(x) | is.na(w)
  46. x <- x[!miss]
  47. w <- w[!miss]
  48. }
  49. sum(w * x) / sum(x)
  50. }
  51. wt_mean(1:4,1:6,na.rm = T)
  52. wt_mean(1:6,1:6,na.rm = "foo")
  53. wt_mean(1:5,1:5,na.rm = F)
  54. #捕获任意数量的未匹配参数...
  55. commas <- function(...)stringr::str_c(...,collapse = ", ")
  56. commas(letters[1:10])
  57. #返回值
  58. #显示返回return(有节制的使用,用于提前返回,一般都是比较简单的情况)
  59. complicated_fun <- function(x,y,z){
  60. if(length(x)==0 || length(y)==0){
  61. return(0)
  62. }
  63. #这里是复杂代码
  64. }
  65. f <- function(){
  66. if(!x){
  67. return("this is not correct")
  68. }
  69. #这里是长的复杂代码
  70. }
  71. #使函数支持管道操作
  72. #环境

--------------第15章 向量------------------------------------------------

  1. typeof(letters)
  2. typeof(1:10)
  3. typeof(1)
  4. typeof(1L)
  5. 1:10 %% 3 == 0
  6. pryr::object_size(x) #占内存空间大小
  7. pryr::object_size(mtcars)
  8. #对象的特性:如名称、维度、类
  9. x <- 1:10
  10. attr(x,"greeting")
  11. attr(x,"greeting") <- "hi" #设置特性
  12. attr(x,"farewell") <- "bye"
  13. attributes(x)
  14. ##泛型函数是R实现面向对象编程的关键,根据不同的输入类型采用不同函数操作。类用来控制泛型函数的运行方式。
  15. as.Date
  16. methods("as.Date")
  17. getS3method("as.Date","default") #查看该方法的实现形式
  18. getS3method("as.Date","numeric")
  19. #最重要的S3泛型函数print()
  20. #基础向量:原子向量和列表
  21. #扩展向量:具有附加特性,包括类。如因子、日期、日期时间、tibble
  22. x <- factor(c("a","b","c"),levels = c("one","two","three"))
  23. typeof(x)
  24. attributes(x)
  25. x <- as.Date("2019-04-14")
  26. unclass(x)
  27. typeof(x)
  28. attributes(x)
  29. x <- lubridate::ymd_hm("1970-01-01 01:00")
  30. unclass(x)
  31. typeof(x)
  32. attributes(x)
  33. tb <- tibble(x=1:5,y=5:1)
  34. typeof(tb)
  35. attributes(tb) #tibble的类继承了data.frame
  36. df <- data.frame(x=1:5,y=5:1)
  37. typeof(df)
  38. attributes(df)

---------------第16章 使用purrr实现迭代----------------------------

  1. #同函数一样,迭代目的也是为减少重复代码
  2. #迭代有命令式编程(for/while循环)和函数式编程
  3. #1.for循环
  4. df <- tibble(a=rnorm(10),
  5. b=rnorm(10),
  6. c=rnorm(10),
  7. d=rnorm(10))
  8. df
  9. #如计算每列的中位值
  10. output <- vector("double",ncol(df)) #输出分配空间,vector函数logical/interger/double/character+长度
  11. for (i in seq_along(df)) { #序列:确定哪些值进行循环
  12. output[[i]] <- median(df[[i]]) #循环体:执行具体操作代码
  13. }
  14. output
  15. output <- c() #每次迭代都用c()来保存结果,对于大处理速度会很慢
  16. for (i in seq_along(df)) { #seq_along(df)等同于1:ncol(df)
  17. output[[i]] <- median(df[[i]]) #循环体 #要向量化
  18. }
  19. output
  20. #在所有for循环中使用的都是[[]],原子向量也是,明确处理的是单个元素
  21. #确定flights数据集中每列的类型
  22. output <- vector("list",ncol(flights))
  23. names(output) <- names(flights)
  24. for (i in names(flights)) {
  25. output[[i]] <- class(flights[[i]])
  26. }
  27. output
  28. #iris数据集中每列唯一值的数目
  29. data("iris")
  30. iris_uniq <- vector("double", ncol(iris))
  31. names(iris_uniq) <- names(iris)
  32. for (i in names(iris)) {
  33. iris_uniq[i] <- length(unique(iris[[i]]))
  34. }
  35. iris_uniq
  36. #用均值分别为-10,0,10,100的正态分布生成10个随机数
  37. n <- 10
  38. mu <- c(-10,0,10,100)
  39. output <- vector("list",length(mu))
  40. for(i in seq_along(output)){
  41. output[[i]] <- rnorm(n,mean = mu[i])
  42. }
  43. output
  44. #等于
  45. matrix(rnorm(n * length(mu), mean = mu), ncol = n)
  46. #2.for循环的变体
  47. ##1)修改现有对象,而不是创建新对象
  48. df
  49. #已经有输出,和输入是相同的
  50. for(i in seq_along(df)){ #序列:数据框是数据列的列表
  51. df[[i]] <- rescale01(df[[i]]) #函数体
  52. }
  53. df
  54. ##2)使用名称或值进行迭代,而非索引
  55. #使用元素循环:for(x in xs),用于绘图或保存文件
  56. #使用名称进行循环:for(nm in names(xs)):图表标题或文件名使用元素,x[[nm]]来访问元素值
  57. results <- vector("list",length(x))
  58. names(results) <- names(x)
  59. #数值索引仍是最常用的方法,给定位置后,就可直接提取元素的名称和值
  60. for(i in seq_along(x)){
  61. name <- names(x)[[i]]
  62. value <- x[[i]]
  63. }
  64. ##3)处理未知长度的输出
  65. #如模拟长度随机的向量,可通过逐渐增加向量长度的方式来实现
  66. means <- c(0,1,2)
  67. output <- double()
  68. for(i in seq_along(means)){
  69. n <- sample(1:100,1)
  70. output <- c(output,rnorm(n,means[[i]]))
  71. }
  72. str(output)
  73. #以上每次迭代都要赋值上次迭代的所有数据,并非高效
  74. #最好先将结果保存在一个列表里,循环结束后再组合成一个新的向量:
  75. out <- vector("list",length(means))
  76. for(i in seq_along(means)){
  77. n <- sample(1:100,1)
  78. out[[i]] <- rnorm(n,means[[i]])
  79. }
  80. str(out)
  81. str(unlist(out))
  82. #同理,如果要生成一个很长的字符串,不要用paste函数将每次迭代结果与上次连接
  83. #而是将每次迭代放在字符向量中,再用paste(output,collapse="")组合起来
  84. #如果要生成一个很大的数据框,不要每次迭代用rbind函数
  85. #而是每次迭代结果保存在列表中,最后再dplyr::bind_rows(output)组合
  86. #用一个更复杂的对象来保存每次迭代结果,最后一次性组合起来
  87. ##4)处理未知长度的序列
  88. #事先不知迭代次数,模拟时最常见,此时用while循环:
  89. #如连续三次丢出正面向上的硬币所需的投掷次数
  90. flip <- function()sample(c("T","H"),1)
  91. flip <- 0
  92. nheads <- 0
  93. while (nheads<3) {
  94. if(flip()=="H"){
  95. nheads <- nheads+1
  96. }else{
  97. nheads <- 0
  98. }
  99. flips <- flips+1
  100. }
  101. flips
  102. #??error:could not find function "flip"
  103. #练习题:
  104. #1.写一个循环批量读取一个目录下的csv文件,并加载到一个数据框
  105. getwd()
  106. files <- dir("data/",pattern = "\\.csv$",full.names = T)
  107. out <- vector("list",length(files))
  108. for(i in seq_along(files)){
  109. out[[i]] <- read.csv(files[[i]])
  110. }
  111. str(out)
  112. df <- bind_rows(out)
  113. #2.写一个函数,能输出iris数据框中所有数值列的均值及其名称,并使数值能整齐排列
  114. head(iris)
  115. show_mean <- function(df, digits = 2) {
  116. # Get max length of all variable names in the dataset
  117. maxstr <- max(str_length(names(df)))
  118. for (nm in names(df)) {
  119. if (is.numeric(df[[nm]])) {
  120. cat(
  121. str_c(str_pad(str_c(nm, ":"), maxstr + 1L, side = "right"),
  122. format(mean(df[[nm]]), digits = digits, nsmall = digits),
  123. sep = " "
  124. ),
  125. "\n"
  126. )
  127. }
  128. }
  129. }
  130. show_mean(iris)
  131. #函数式编程:将for循环包装在函数中,再调用函数
  132. #将函数作为参数传入另一个函数中
  133. #编写一个函数计算数据框每列均值、中位数、标准差等
  134. col_summary <- function(df,fun){
  135. out <- vector("double",length(df))
  136. for(i in seq_along(df)){
  137. out[i] <- fun(df[[i]])
  138. }
  139. out
  140. }
  141. df <- tibble(
  142. a=rnorm(10),
  143. b=rnorm(10),
  144. c=rnorm(10),
  145. d=rnorm(10)
  146. )
  147. col_summary(df,median)
  148. col_summary(df,mean)
  149. col_summary(df,sd)
  150. #映射函数:处理列表、数据框
  151. #类似基础函数apply族函数:计算每列
  152. map(df,mean) #返回列表
  153. map_dbl(df,sd) #返回双精度向量
  154. map_chr(df,mean) #返回字符向量
  155. map_int()#返回整型向量
  156. map_lgl() #返回逻辑向量
  157. #map函数可加参数:
  158. map_dbl(df,mean,trim=0.5)
  159. #快捷方式.f
  160. models <- mtcars %>%
  161. split(.$cyl) %>%
  162. map(function(df) lm(mpg~wt,data=df))
  163. #等于
  164. models <- mtcars %>%
  165. split(.$cyl) %>%
  166. map(~lm(mpg~wt,data=.)) #.表示当前列表元素
  167. models %>% map(summary) %>% map_dbl(~.$r.squared)
  168. models %>% map(summary) %>% map_dbl("r.squared")
  169. x <- list(list(1,2,3),list(4,5,6),list(7,8,9))
  170. x %>% map_dbl(2) #按位置选取元素
  171. #对操作失败的处理
  172. safely()#类似基础函数try()
  173. safe_log <- safely(log)
  174. str(safe_log(10))
  175. str(safe_log("a"))
  176. #修饰函数
  177. possibly()/quietly()
  178. #多参数映射:map2()/pmap()
  179. #模拟几个均值不等的随机正态分布
  180. mu <- list(5,10,-3)
  181. mu %>% map(rnorm,n=5) %>% str
  182. #再加个参数,让标准差也不同
  183. sigma <- list(1,5,10)
  184. map2(mu,sigma,rnorm,n=5) %>% str
  185. #如果再加一个样本数参数呢?可用列表/数据框作为参数传入
  186. n <- list(1,3,5)
  187. args1 <- list(n,mu,sigma)
  188. args1 %>% pmap(rnorm) %>% str
  189. #使用命名参数无需按位置对应,更为安全
  190. args2 <- list(mean=mu,sd=sigma,n=n)
  191. args2 %>% pmap(rnorm) %>% str
  192. #游走函数:重在操作过程,而非返回值
  193. x <- list(1,"a",3)
  194. x %>% walk(print)
  195. #预测函数
  196. #keep/discard保留输入值中预测值为TRUE/FALSE的元素
  197. iris %>% keep(is.factor) %>% str
  198. iris %>% discard(is.factor) %>% str
  199. #some/every确定预测值是否对某个元素/所有元素为真
  200. x <- list(1:5,letters,list(10))
  201. x %>% some(is_character)
  202. x %>% every(is_vector)
  203. #detect/detect_index找出预测值为真的第一个元素/索引
  204. x <- sample(10)
  205. x
  206. x %>% detect(~.>5)
  207. x %>% detect_index(~.>5)
  208. #head_while/tail_while从向量的开头/结尾找出预测值为真的元素
  209. x %>% head_while(~.>5)
  210. x %>% tail_while(~.>5)
  211. #归约函数reduce
  212. #尤其适合多个数据框合并,多个向量取交集等情况
  213. dfs <- list(
  214. age=tibble(name="jianxiang",age=18),
  215. sex=tibble(name=c("jianxiang","siyuan"),sex=c("M","F")),
  216. trt=tibble(name="siyuan",treatment="A")
  217. )
  218. dfs %>% reduce(full_join)
  219. vs <- list(c(1:5),c(3:8),c(4:10))
  220. vs %>% reduce(intersect)
  221. #累计函数accumulate,会保留所有累计中间结果
  222. x <- sample(10)
  223. x
  224. x %>% accumulate(`+`)
  225. #练习
  226. #将摘要函数应用于数据框的每个数值列:
  227. col_sum2 <- function(df, f, ...) {
  228. map(keep(df, is.numeric), f, ...)
  229. }

R数据科学-3的更多相关文章

  1. 学习《R数据科学》高清中文PDF+高清英文PDF+源代码

    学习R有不会的就查工具书<R数据科学>, 工具不是重点,创造价值才是目的.具体到数据科学,表现形式往往是提供解决方案或者做出某种决策.至于使用什么语言,采用什么工具,不本质.用 R 还是 ...

  2. R数据科学-2

    R数据科学(R for Data Science) Part 2:数据处理 导入-->整理-->转换 ------------------第7章 使用tibble实现简单数据框------ ...

  3. R数据科学-1

    R数据科学(R for Data Science) Part 1:探索 by: PJX for 查漏补缺 exercise: https://jrnold.github.io/r4ds-exercis ...

  4. 深入对比数据科学工具箱:Python和R之争

    建议:如果只是处理(小)数据的,用R.结果更可靠,速度可以接受,上手方便,多有现成的命令.程序可以用.要自己搞个算法.处理大数据.计算量大的,用python.开发效率高,一切尽在掌握. 概述 在真实的 ...

  5. 数据科学实战手册(R+Python)书中引用资料网址

    本文会持续将<数据科学实战手册(R+Python)>一书中的附带参考资料网址手打出来, 方便访问. 由于书中的参考资料网址太多, 这个文档将可能花费一段时间才能完成. 第一章 P7  Rs ...

  6. (数据科学学习手札07)R在数据框操作上方法的总结(初级篇)

    上篇我们了解了Python中pandas内封装的关于数据框的常用操作方法,而作为专为数据科学而生的一门语言,R在数据框的操作上则更为丰富精彩,本篇就R处理数据框的常用方法进行总结: 1.数据框的生成 ...

  7. R学习:《机器学习与数据科学基于R的统计学习方法》中文PDF+代码

    当前,机器学习和数据科学都是很重要和热门的相关学科,需要深入地研究学习才能精通. <机器学习与数据科学基于R的统计学习方法>试图指导读者掌握如何完成涉及机器学习的数据科学项目.为数据科学家 ...

  8. 机器学习与数据科学 基于R的统计学习方法(基础部分)

    1.1 机器学习的分类 监督学习:线性回归或逻辑回归, 非监督学习:是K-均值聚类, 即在数据点集中找出“聚类”. 另一种常用技术叫做主成分分析(PCA) , 用于降维, 算法的评估方法也不尽相同. ...

  9. [数据科学] 从text, json文件中提取数据

    文本文件是基本的文件类型,不管是csv, xls, json, 还是xml等等都可以按照文本文件的形式读取. #-*- coding: utf-8 -*- fpath = "data/tex ...

随机推荐

  1. 【数据结构与算法Python版学习笔记】引言

    学习来源 北京大学-数据结构与算法Python版 目标 了解计算机科学.程序设计和问题解决的基本概念 计算机科学是对问题本身.问题的解决.以及问题求解过程中得出的解决方案的研究.面对一 个特定问题,计 ...

  2. OO第三单元JML总结

    目录 目录一.JML语言的理论基础二.应用工具链三.部署SMT Solver四.部署JMLUnitNG/JMLUnit五.三次作业分析第一次作业第二次作业第三次作业六.总结与心得体会 一.JML语言的 ...

  3. 计算机网络之网络层移动IP

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/105319753 学习课程:<2019王道考研计算机网络> 学习目的 ...

  4. 洛谷 P2252 [SHOI2002]取石子游戏|【模板】威佐夫博弈

    链接: P2252 [SHOI2002]取石子游戏|[模板]威佐夫博弈 前言: 第一眼大水题,第二眼努力思考,第 N 眼我是大水逼. 题意: 不看题目标题都应该能看出来是取石子类的博弈论. 有两堆石子 ...

  5. 到底能不能用 join

    互联网上一直流传着各大公司的 MySQL 军规,其中关于 join 的描述,有些公司不推荐使用 join,而有些公司则规定有条件的使用 join, 它们都是教条式的规定,也没有详细说其中的原因,这就很 ...

  6. linux Segmentation faults 段错误详解

    什么是段错误 下面是来自 Answers.com 的定义: A segmentation fault (often shortened to segfault) is a particular err ...

  7. 数组中只出现过一次的数字 牛客网 剑指Offer

    数组中只出现过一次的数字 牛客网 剑指Offer 题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了偶数次.请写程序找出这两个只出现一次的数字. def FindNumsAppearOnce ...

  8. 反转单词顺序列 牛客网 剑指Offer

    反转单词顺序列 牛客网 剑指Offer 题目描述 牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但 ...

  9. 正则表达式匹配 牛客网 剑指Offer

    正则表达式匹配 牛客网 剑指Offer 题目描述 请实现一个函数用来匹配包括'.'和''的正则表达式.模式中的字符'.'表示任意一个字符,而''表示它前面的字符可以出现任意次(包含0次). 在本题中, ...

  10. Java学习笔记:GUI基础

    一:我们使用到的java GUI的API可以分为3种类: 组件类(component class) 容器类(container class) 辅助类(helper class) 1:组件类:组件类是用 ...