r语言clind函数_19 函数进阶 | R语言教程

19.5.3 跟踪调试

R和RStudio提供了很好的跟踪运行程序的能力。

R的browser()命令可以用在程序中,

命令进入跟踪调试;

RStudio的源文件显示界面可以用鼠标点击定义跟踪调试位置。

函数定义一般都包含多行,所以一般不在命令行定义函数,

而是把函数定义以及较长的程序写在源程序文件中,

用source命令运行。

用source命令调入运行的程序与在命令行运行的效果基本相同,

这样定义的变量也是全局变量。

考虑如下函数定义:

f

for(i in 1:n){

s

}

}

这个函数定义有许多问题。

用一个测试输入调用f,发现有错误:

print(f(1:5))

## Error in 1:n : NA/NaN参数

简单的函数可以直接仔细检查发现错误,

用cat, print等输出中间结果查找错误。

R提供了一个browser()函数,

在程序中插入对browser()函数的调用,

可以进入跟踪调试状态,

可以实时地查看甚至修改运行时变量的值。

在RStudio的编辑窗口中打开.R源程序文件,

在某一程序行行号左端的空白处用鼠标单击,

就可以设定某一行为端点,

在用source命令运行到该处时就可以进入跟踪调试状态。

加入browser()命令后的程序如:

f

browser()

for(i in 1:n){

s

}

}

程序运行遇到browser()函数或设定的断点时程序进入跟踪调试状态,

命令行的提示符变成“Browse[1]>”。

这个命令行的环境一般不再是全局环境,

而是断点所在的函数的运行环境,

可以看到函数的局部变量。

可以在调试环境中用命令去查看当前定义的变量值、逐个命令地运行,

但是用RStudio则可以更方便地执行这些操作。

在调试命令行,可以使用如下命令:

输入变量名查看变量值;

用n命令或者换行键逐句运行;

用s命令跟踪进调用的函数内部逐句运行;

用f命令快速执行到循环末尾或者函数末尾;

用c命令恢复正常运行,不再跟踪;

用Q命令强行终止程序运行。

进入调试状态后,

RStudio界面提供了相应的支持。

这时RStudio的命令行窗格(Console)将会显示用于控制运行的图标,

包括执行下一语句(Next)、跟踪进入要调用的函数运行(Step into)、执行到函数末尾或者循环末尾(Finish)、不再跟踪继续正常运行(Continue)、终止运行(Stop)。

同时,

在RStudio的Environment窗格中会显示当前执行的命令所在的运行环境的内容,

包括函数内的局部变量;

如果点击其中的下拉菜单还可以显示函数的各层父环境。

在同一窗格中还会显示向后追踪(Traceback),

即函数是如何被调用的。

为调试如上函数f的程序,

在定义中插入对browser()的调用如:

f

browser()

for(i in 1:n){

s

}

}

当在RStudio中调试运行时,

程序编辑窗口将显示当前要运行的程序行,

用命令行窗口(Console)的Next快捷图标可以运行到下一行。

命令行的显示如:

> print(f(1:5))

Called from: eval(expr, p)

Browse[1]> n

debug在D:/disk/projects/Rbookweb/tmp2.R#2: for (i in 1:n) {

s

}

Browse[2]>

继续用“Next”图标运行,命令行结果如:

Browse[2]> n

Error in 1:n : NA/NaN参数

发现是在for(i in 1:n)行遇到未定义的变量n。

在源文件中把出错行改为for(i in 1:length(x)),

再次运行,

发现在运行s

遇到“错误: 找不到对象’s’”。

这是忘记初始化引起的。

在for语句前添加s

f

browser()

s

for(i in 1:length(x)){

s

}

}

再次运行,

在跟踪到循环时,

为了避免繁琐的跟踪过程,

可以用“执行到函数末尾或者循环末尾”快捷图标或命令行的f命令,

或者“Continue”快捷图标或命令行的c命令。

程序不显示错误但是也没有显示结果为NULL而不是我们期望得输入元素之和。

检查可以看出错误是忘记把函数返回值写在函数定义最后。

在函数定义最后添加s一行,

再次运行,程序结果与手工验算结果一致。

函数变成

f

browser()

n

s

for(i in 1:n){

s

}

s

}

自定义函数应该用各种不同输入测试其正确性和稳定性。

比如,上面的函数当自变量x为零长度向量时应该返回0才合适,

但是上面的写法会返回一个numeric(0)结果,

这个结果表示长度为零的向量:

f(numeric(0))

## Called from: f(numeric(0))

## Browse[1]> c

## numeric(0)

程序输入了零长度自变量,

我们期望其输出为零而不是numeric(0)。

在自变量x为零长度时,

函数中for(i in 1:length(x)应该一次都不进入循环,

跟踪运行可以发现实际对i=1和i=0共运行了两轮循环。

把这里的1:length(x)改成seq_along(x)解决了问题,

seq_along(x)生成x的下标序列,

如果x是零长度的则下标序列为零长度向量。

函数不需要修改后,

可以把对browser()的调用删除或注释掉,

在RStudio中关闭断点。

函数最终修改为:

f

s

for(i in seq_along(x)){

s

}

s

}

这里只是用这个简单函数演示如何调试程序,

求向量元素和这个问题本身是不需要我们去定义新函数的,

sum函数本来就是完成这样的功能。

实际上,许多我们认为需要自己编写程序做的事情,

在R网站都能找到别人已经完成的扩展包。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值