数据科学05 | R语言程序设计-调试工具与str函数
调试工具debugging tools
➢条件condition
用于提示运行函数过程中意外事件或错误的发生,编写函数时可以自行创造新的提示条件。
message:由message()产生,输出提示信息到Console控制台,不会阻止函数运行
warning:由warning()产生,运行过程出现潜在的问题,函数继续执行,完全执行后输出警告
error:由stop()产生,运行过程出现重大问题无法继续,强制终止运行
#warning
log(-1)
[1] NaN
Warning message:
In log(-1) : 产生了NaNs
#取一个负数的常用对数,返回NaN表示非数字 (Not a number)
#error
printmessage <- function(x) {
if(x>0)
print("x is greater than zero")
else
print("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 found
traceback()
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 <- x
ret.y <- y
cl <- 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 <- TRUE
mf[[1L]] <- quote(stats::model.frame)
mf <- eval(mf, parent.frame())
...
if (!qr)
z$qr <- NULL
z
}
Browse[2]> n
debug: ret.x <- x
Browse[2]> n
debug: ret.y <- y
Browse[2]> n
debug: cl <- match.call()
Browse[2]> n
debug: mf <- match.call(expand.dots = FALSE)
Browse[2]> n
debug: m <- match(c("formula", "data", "subset", "weights", "na.action",
"offset"), names(mf), 0L)
Browse[2]> n
debug: mf <- mf[c(1L, m)]
Browse[2]> n
debug: mf$drop.unused.levels <- TRUE
Browse[2]> n
debug: mf[[1L]] <- quote(stats::model.frame)
Browse[2]> n
debug: mf <- eval(mf, parent.frame())
Browse[2]> n
Error 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 directory
1: read.csv("nosuchfile")
2: read.table(file = file, header = header, sep = sep, quote = quote, dec
3: 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.2853
str(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 20
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
10 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 Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
4 18 313 11.5 62 5 4
5 NA NA 14.3 56 5 5
6 28 NA 14.9 66 5 6
str(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个观测数据。