问题 如何在RStudio中调试(放置断点等)已安装的R包?


我需要逐行运行一个函数来理解它是如何工作的。但是该函数是已安装软件包的一部分,我不知道R在哪里存储已安装软件包的源(比如MultiPhen)。我在Ubuntu 12(64it)中使用RStudio 0.98.501和R 3.0.2。显然没有存储已安装软件包的源代码,对吧?对不起,如果这是一个天真的问题,我是R的新手。 如果没有存储源,那么无论如何都要重新安装带有源的包并进行调试(基本上放置一个断点)。

谢谢,

世界报


1316
2018-02-24 22:58


起源



答案:


看着 trace。下面是在基本包函数的第四个语句中添加断点的示例 var。我们在这里问 trace 调用该函数 browser 在第六个声明:

> trace(var, browser, at=6)
Tracing function "var" in package "stats"
[1] "var"
> var(1:10)
Tracing var(1:10) step 6 
Called from: eval(expr, envir, enclos)
Browse[1]> n
debug: if (is.data.frame(y)) y <- as.matrix(y) else stopifnot(is.atomic(y))
Browse[2]> n
debug: stopifnot(is.atomic(y))
Browse[2]> n
debug: .Call(C_cov, x, y, na.method, FALSE)
Browse[2]> n
[1] 9.166667

记得 untrace 当你完成了。你可以做相当复杂的事情 trace,尽管在大多数情况下 trace(fun.name, browser) 可能就够了。

或者,您可以只加载包并在命令行上键入函数的名称,如下所示:

> var
function (x, y = NULL, na.rm = FALSE, use) 
{
    if (missing(use)) 
        use <- if (na.rm) 
            "na.or.complete"
        else "everything"
    na.method <- pmatch(use, c("all.obs", "complete.obs", "pairwise.complete.obs", 
        "everything", "na.or.complete"))
    if (is.na(na.method)) 
        stop("invalid 'use' argument")
    if (is.data.frame(x)) 
        x <- as.matrix(x)
    else stopifnot(is.atomic(x))
    if (is.data.frame(y)) 
        y <- as.matrix(y)
    else stopifnot(is.atomic(y))
    .Call(C_cov, x, y, na.method, FALSE)
}
<bytecode: 0x000000000928ad30>
<environment: namespace:stats>

然后,您可以将其复制到编辑器中并使用它,添加您的 browser 声明,并逐步完成结果。


14
2018-02-24 23:21



谢谢,它非常强大! - kayhan


答案:


看着 trace。下面是在基本包函数的第四个语句中添加断点的示例 var。我们在这里问 trace 调用该函数 browser 在第六个声明:

> trace(var, browser, at=6)
Tracing function "var" in package "stats"
[1] "var"
> var(1:10)
Tracing var(1:10) step 6 
Called from: eval(expr, envir, enclos)
Browse[1]> n
debug: if (is.data.frame(y)) y <- as.matrix(y) else stopifnot(is.atomic(y))
Browse[2]> n
debug: stopifnot(is.atomic(y))
Browse[2]> n
debug: .Call(C_cov, x, y, na.method, FALSE)
Browse[2]> n
[1] 9.166667

记得 untrace 当你完成了。你可以做相当复杂的事情 trace,尽管在大多数情况下 trace(fun.name, browser) 可能就够了。

或者,您可以只加载包并在命令行上键入函数的名称,如下所示:

> var
function (x, y = NULL, na.rm = FALSE, use) 
{
    if (missing(use)) 
        use <- if (na.rm) 
            "na.or.complete"
        else "everything"
    na.method <- pmatch(use, c("all.obs", "complete.obs", "pairwise.complete.obs", 
        "everything", "na.or.complete"))
    if (is.na(na.method)) 
        stop("invalid 'use' argument")
    if (is.data.frame(x)) 
        x <- as.matrix(x)
    else stopifnot(is.atomic(x))
    if (is.data.frame(y)) 
        y <- as.matrix(y)
    else stopifnot(is.atomic(y))
    .Call(C_cov, x, y, na.method, FALSE)
}
<bytecode: 0x000000000928ad30>
<environment: namespace:stats>

然后,您可以将其复制到编辑器中并使用它,添加您的 browser 声明,并逐步完成结果。


14
2018-02-24 23:21



谢谢,它非常强大! - kayhan


  1. 我认为,当你打字的时候 install.packages('MultiPhen') 你得到了包的二进制版本。我认为没有办法设置断点并通过该版本的包逐步执行代码。

  2. 所有R软件包都是开源的,源代码可以在软件包的CRAN页面上找到。例如, 这个 是MultiPhen的CRAN页面。如果单击文本“Package source:”旁边的链接,则将下载源代码。

  3. 在拥有源代码时该怎么做:所有R包都具有相同的目录结构。对于您的情况最重要的是,包的所有R代码都在名为“R”的目录中。

我建议从RStudio卸载软件包并在“R”目录中获取代码,设置断点并根据需要单步执行代码。

如果这可以解决您的问题,请告诉我们。


1
2018-02-24 23:25



谢谢,我已经阅读了源码,但我需要逐行运行才能理解它。因此,如果卸载了一个包并且源处于活动路径,那么“library(MultiPhen)”是否仍会加载该包?否则如何加载它? - kayhan
乐意效劳。在你的情况下,我会忘记 library 完全命令。我也不会考虑将MultiPhen作为一个包。相反,我会把它想象成我在本地机器上碰巧有的5个文件。我会在RStudio中打开这些文件,为每个文件单击“Source”,并在我想要的地方设置断点。从本质上讲,我会对待那些文件,我会自己编写任何代码。代码来源后,我会从控制台调用我感兴趣的函数。这回答了你的问题了吗? - Ari
谢谢,是的,你回答了我的问题。我想我几周前尝试了你的建议,我遇到了一些奇怪的函数定义问题,但也许我不够小心。我目前正在使用trace()(另一个答案)并且它正在运行。非常感谢 :) - kayhan
真高兴你做到了。我其实并不知道 trace() 当我写下答案的时候。看起来我们今天都学到了新东西! - Ari