数据科学05 | R语言程序设计-调试工具与str函数
调试工具debugging tools
➢条件condition
用于提示运行函数过程中意外事件或错误的发生,编写函数时可以自行创造新的提示条件。
message:由message()产生,输出提示信息到Console控制台,不会阻止函数运行
warning:由warning()产生,运行过程出现潜在的问题,函数继续执行,完全执行后输出警告
error:由stop()产生,运行过程出现重大问题无法继续,强制终止运行
#warninglog(-1)[1] NaNWarning message:In log(-1) : 产生了NaNs#取一个负数的常用对数,返回NaN表示非数字 (Not a number)#errorprintmessage <- function(x) {if(x>0)print("x is greater than zero")elseprint("x is less than or equal to zero")invisible(x)}printmessage(1)[1] "x is greater than zero"printmessage(NA)Error in if (x > 0) print("x is greater than zero") else print("x is less than or equal to zero") :需要TRUE/FALSE值的地方不可以用缺少值
➢调试函数时按以下流程考虑问题
1)实际输入函数的是什么?
2)预期结果是什么?
3)怎么调用函数?参数是什么?
4)实际结果和预期结果之间有何区别?
5)最初的预期是否正确?
6)能否重塑问题?(如设定随机数种子,重复产生问题的过程)
➢R中的调试工具
traceback 函数:打印函数调用栈 (function call stack),说明一共调用了多少个函数,以及错误发生的位置
debug 函数:传递一个函数作为参数,可以标记这个函数,进入调试模式(debug mode)
调试模式(debug mode):每当执行到这个函数时都会暂停执行,停在这个函数的第一行
browser 函数:在代码的任何地方调用 browser(),函数会停止执行,能从那里开始逐行运行,找出出现错误的代码具体是哪一行
trace 函数:trace 函数允许在函数中插入调试代码,避免了编辑函数本身
recover 函数:R默认在报错之后回到控制台,通过设置错误处理器 (error handler)可改变这种默认行为。recover() 是错误处理函数,函数遇到错误时R编译器停止执行,但不回到控制台,会停在函数出错的地方,输出函数调用栈。
lm(y~x)Error in eval(expr, envir, enclos) : object ’y’ not foundtraceback()7: eval(expr, envir, enclos)6: eval(predvars, data, env)5: model.frame.default(formula = y ~ x, drop.unused.levels = TRUE)4: model.frame(formula = y ~ x, drop.unused.levels = TRUE)3: eval(expr, envir, enclos)2: eval(mf, parent.frame())1: lm(y~x)
出错在第7层函数,出错原因是它试图解析公式y~x,eval()在解析公式时无法找到 y 和 x 的实际值。
必须在错误发生后马上调用 traceback函数,traceback函数只能给出上一次执行的错误。
debug(lm)lm(y~x)debugging in: lm(y ~ x)debug: {ret.x <- xret.y <- ycl <- match.call()mf <- match.call(expand.dots = FALSE)m <- match(c("formula", "data", "subset", "weights", "na.action","offset"), names(mf), 0L)mf <- mf[c(1L, m)]mf$drop.unused.levels <- TRUEmf[[1L]] <- quote(stats::model.frame)mf <- eval(mf, parent.frame())...if (!qr)z$qr <- NULLz}Browse[2]> ndebug: ret.x <- xBrowse[2]> ndebug: ret.y <- yBrowse[2]> ndebug: cl <- match.call()Browse[2]> ndebug: mf <- match.call(expand.dots = FALSE)Browse[2]> ndebug: m <- match(c("formula", "data", "subset", "weights", "na.action","offset"), names(mf), 0L)Browse[2]> ndebug: mf <- mf[c(1L, m)]Browse[2]> ndebug: mf$drop.unused.levels <- TRUEBrowse[2]> ndebug: mf[[1L]] <- quote(stats::model.frame)Browse[2]> ndebug: mf <- eval(mf, parent.frame())Browse[2]> nError in eval(predvars, data, env) : 找不到对象'y'
调试模式下运行lm(y~x)将打印函数的所有代码,向提示符Browse[2]>一直输入n逐行运行,直到找到出错的那一行。
options(error = recover)#options()设置全局选项,把recover函数设为错误处理器read.csv("nosuchfile") #读取一个不存在的csv文件Error in file(file, "rt") : 无法打开链结此外: Warning message:In file(file, "rt") : 无法打开文件'nosuchfile': No such file or directory1: read.csv("nosuchfile")2: read.table(file = file, header = header, sep = sep, quote = quote, dec3: file(file, "rt")Selection:
・报错后没有返回控制台,而是输入函数调用栈。
・错误发生在函数调用栈的第3级,当函数试图建立文件关联的时候找不到文件
・输入数字1、2、3,可以浏览函数环境,查看每个调用的函数中都发生了什么
str函数
str 函数可以紧凑地显示 R 对象的内部结构,可以代替 summary 函数,特别适用于大型列表。
➢函数
str(str)function (object, ...)
x <- rnorm(100, 2, 4)summary(x)Min. 1st Qu. Median Mean 3rd Qu. Max.-9.9878 -0.6826 2.5642 2.1066 4.7830 11.2853str(x)num [1:100] 2.889 0.892 7.577 -0.636 4.642 ...
summary()返回6个概括统计量,粗略说明数据集的范围和离散情况。
str() 说明 x 是一个数值向量,含有100个元素,及向量 x 的前五个数。
f <- gl(40, 10)str(f)Factor w/ 40 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 1 1 ...summary(f)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 2010 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1021 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 4010 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
➢数据框
library(datasets)head(airquality)Ozone Solar.R Wind Temp Month Day1 41 190 7.4 67 5 12 36 118 8.0 72 5 23 12 149 12.6 74 5 34 18 313 11.5 62 5 45 NA NA 14.3 56 5 56 28 NA 14.9 66 5 6str(airquality): 153 obs. of 6 variables:Ozone : int 41 36 12 18 NA 28 23 19 8 NA ...Solar.R: int 190 118 149 313 NA NA 299 99 19 194 ...Wind : num 7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ...Temp : int 67 72 74 62 56 66 65 59 61 69 ...Month : int 5 5 5 5 5 5 5 5 5 5 ...Day : int 1 2 3 4 5 6 7 8 9 10 ...
str()说明对象是数据框,有153个观测值,6个变量,输出每个变量的一些元素以及变量类型,为整数型变量和数值型变量。
➢矩阵
m <- matrix(rnorm(100), 10, 10)str(m)num [1:10, 1:10] -0.483 -0.669 0.513 1.049 0.121 ...
str()说明对象是矩阵,有10行10列,并列出前几个元素。
➢列表
s <- split(airquality, airquality$Month)str(s)List of 5$ 5:'data.frame': 31 obs. of 6 variables:..$ Ozone : int [1:31] 41 36 12 18 NA 28 23 19 8 NA .....$ Solar.R: int [1:31] 190 118 149 313 NA NA 299 99 19 194 .....$ Wind : num [1:31] 7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 .....$ Temp : int [1:31] 67 72 74 62 56 66 65 59 61 69 .....$ Month : int [1:31] 5 5 5 5 5 5 5 5 5 5 .....$ Day : int [1:31] 1 2 3 4 5 6 7 8 9 10 ...$ 6:'data.frame': 30 obs. of 6 variables:..$ Ozone : int [1:30] NA NA NA NA NA NA 29 NA 71 39 .....$ Solar.R: int [1:30] 286 287 242 186 220 264 127 273 291 323 .....$ Wind : num [1:30] 8.6 9.7 16.1 9.2 8.6 14.3 9.7 6.9 13.8 11.5 .....$ Temp : int [1:30] 78 74 67 84 85 79 82 87 90 87 .....$ Month : int [1:30] 6 6 6 6 6 6 6 6 6 6 .....$ Day : int [1:30] 1 2 3 4 5 6 7 8 9 10 ...$ 7:'data.frame': 31 obs. of 6 variables:..$ Ozone : int [1:31] 135 49 32 NA 64 40 77 97 97 85 .....$ Solar.R: int [1:31] 269 248 236 101 175 314 276 267 272 175 .....$ Wind : num [1:31] 4.1 9.2 9.2 10.9 4.6 10.9 5.1 6.3 5.7 7.4 .....$ Temp : int [1:31] 84 85 81 84 83 83 88 92 92 89 .....$ Month : int [1:31] 7 7 7 7 7 7 7 7 7 7 .....$ Day : int [1:31] 1 2 3 4 5 6 7 8 9 10 ...$ 8:'data.frame': 31 obs. of 6 variables:..$ Ozone : int [1:31] 39 9 16 78 35 66 122 89 110 NA .....$ Solar.R: int [1:31] 83 24 77 NA NA NA 255 229 207 222 .....$ Wind : num [1:31] 6.9 13.8 7.4 6.9 7.4 4.6 4 10.3 8 8.6 .....$ Temp : int [1:31] 81 81 82 86 85 87 89 90 90 92 .....$ Month : int [1:31] 8 8 8 8 8 8 8 8 8 8 .....$ Day : int [1:31] 1 2 3 4 5 6 7 8 9 10 ...$ 9:'data.frame': 30 obs. of 6 variables:..$ Ozone : int [1:30] 96 78 73 91 47 32 20 23 21 24 .....$ Solar.R: int [1:30] 167 197 183 189 95 92 252 220 230 259 .....$ Wind : num [1:30] 6.9 5.1 2.8 4.6 7.4 15.5 10.9 10.3 10.9 9.7 .....$ Temp : int [1:30] 91 92 93 93 87 84 80 78 75 73 .....$ Month : int [1:30] 9 9 9 9 9 9 9 9 9 9 .....$ Day : int [1:30] 1 2 3 4 5 6 7 8 9 10 ...
通过month变量来分割airquality数据框,对 s 调用str()。可以看到得到一个包含有5个不同的数据框的列表,每个数据框对应特定的月份,5月有6个变量,31个观测数据。
