《R语言初学指南》一2.3 找到R脚本中的错误

本节书摘来自异步社区《R语言初学指南》一书中的第2章,第2.3节,作者【美】Brian Dennis(布莱恩·丹尼斯),更多章节内容可以访问云栖社区“异步社区”公众号查看

2.3 找到R脚本中的错误

R语言初学指南
复杂项目中的R脚本会非常长。即使是R专家,也很少能一次性将其编写正确。脚本中的所有错误都是通过调试来修改的。

在脚本中称追踪错误或“bug”为“调试”。调试包括一些适用性检测工作。

下面在脚本中故意制造一个bug,由此来练习如何调试。首先来做一些清理工作。使控制台成为活动窗口,并输入下列命令:

>objects()

按照惯例,这里在展示控制台中的命令时,依然在其前面显示R提示符(“>”),但要记住,在控制台中不需要输入该提示符。不要忘记命令末尾的括号。在运行该命令后,就可在工作区内看到一串已用R命令建立好的“对象”:

[1] "a"       "b"       "k"       "kill.rate"  
[5] "m"       "moose.density"

这些对象已存储在R中,可供日后调用。现在输入下列命令:

>rm(a,b,k,kill.rate,m,moose.density)
>a

哎?找不到对象a了,其他几个对象也找不到。命令rm()表示“移除”,它会删除括号中的所有对象。由于用户可能会忘记之前在R会话中建立的对象,而导致后面的计算出现错误,这时命令objects()和rm()就会非常有用。

现在开始通过制造bug来搞破坏!回到R编辑器中,将脚本的第一个命令moose.density的首字母改为大写字母M,然后重新运行脚本。这时会弹出图形窗口,但其中没有图形显示——出现错误了。看一下控制台,找到与下列语句相似的内容(在不同版本的R中,出现的错误信息可能会稍有不同):

> Moose.density=c(.17,.23,.23,.26,.37,.42,.66,.80,1.11,1.30,1.37,
+ 1.41,1.73,2.49)
> kill.rate=c(.37,.47,1.90,2.04,1.12,1.74,2.78,1.85,1.88,1.96,
+ 1.80,2.44,2.81,3.75)
> plot(moose.density,kill.rate,type="p")
Error in plot(moose.density, kill.rate, type = "p") :
 object 'moose.density' not found
> m=2.5*(0:100)/100
> a=3.37
> b=0.47
> k=a*m/(b+m)
> points(m,k,type="l")
Error in plot.xy(xy.coords(x, y), type = type, ...) :
 plot.new has not been called yet

控制台中重现了脚本,其中还包含两条错误信息。这里有两点非常重要,需要注意。

首先,尽管没有修改plot()语句和points()语句,但它们下面出现了错误信息,而实际上有错误(大写字母M)的语句却没有任何提示。在脚本中,错误可以影响下面一系列命令出错。这里,定义向量Moose.density的命令是一个在R中完全正确的语句,它在R的内存中建立了对象Moose.density以便日后调用,在控制台中使用object()命令即可看到这一对象。问题出在绘图语句上。plot()语句使用的向量moose.density并不存在,故plot()语句无法进行绘图。接着由于没有元素可以添加到图形中,points()语句也就无法执行。

其次,在通常情况下,若可以定位并修正某个错误,则后面的一些错误也会被修正。因此,建议用户在策略上,要从上到下一个一个地修改错误。此外,在每修改完一个语句或一小部分R脚本后,就对它们进行测试,以防修改本身包含错误并对后续的语句产生影响。不过,即使再小心谨慎,也几乎没有很长的R脚本可在第一次就能完美地运行出来。

若要在脚本中检测并定位不明显的错误,需要对脚本从头开始进行一系列搜索及实验。在空白的工作区中,可选中代码并运行这部分脚本,从而很方便地完成这一任务。读者可以试一下:首先像刚才一样,在控制台中删除工作区内的所有对象,然后在R编辑器中选中第一个命令,使其高亮。在“Edit”的下拉菜单中(在微软的Windows中,若对高亮区点击右键,会弹出菜单),找到并点击“Run line selection”选项,即可运行脚本中的第一行命令。在控制台中检查一下,这条命令建立了哪些对象。

若该命令的运行情况与预期一致,则继续运行下一条语句。单独选中并运行下一条语句,然后再连同脚本中前面的语句一起运行一遍。

当检查到绘图语句时,错误信息就会出现。绘图命令在寻找一个不存在的对象。若在之前的检查中没有发现Moose.density与moose.density是两个不同的对象,这时也许能清晰地发现这一点。R的用户应当时刻注意变量名的大小写以及拼写错误问题,这是错误的一个主要来源。

找到并改正大写的M,然后运行脚本,即可成功绘图。但是等一下:过早地认为这是一个完美的脚本可能会导致失败。有时即使脚本可以很好地运行,其运行结果也可能错得离谱。当计算本身有概念性的错误时,这种情况就会发生。R会精确完成用户的指令,且当用户的指令有错误时,R也会按错误指令忠实地运行完成。

数据输入是否正确?作者在输入本章数据时,是否与第1章保持一致了呢?要想有效地使用R,仔细一点儿总不会错。

上一篇:DNS服务配置|学习笔记


下一篇:使用python和批处理bat脚本ping检测主机连通性