【问题标题】:Some plots not rendering in Rstudio, knitr, Rmarkdown在 Rstudio、knitr、Rmarkdown 中没有渲染的一些图
【发布时间】:2013-10-17 15:21:08
【问题描述】:

我正在使用: Ubuntu 12.04 64 位, R 3.0.2, RStudio 0.98.312, 针织机 1.5, 降价0.6.3, mgcv1.​​7-27

我有一个包含多个代码块的 Rmarkdown 文档。在一块的中间有一些代码,我适合 GAM,总结适合度并绘制适合度。问题是第一个图渲染到输出文件中,但第二个图没有。这是来自该块的经过净化的代码片段:

fit <- gam(y ~ s(x), data=j0, subset= !is.na(x))
summary(fit) # look at non-missing only
plot(fit)

fit <- gam(y ~ s(sqrt(x)), data=j0, subset= !is.na(x))
summary(fit)
plot(fit)

mean(y[is.na(x)]) - mean(y[!is.na(x)])

一切都按预期呈现,除了输出直接从回显第二个绘图语句到回显下面的均值计算。均值计算的结果正确呈现。

如果我在块的后面 7 行注释掉另一个绘图调用,那么丢失的绘图将正确呈现。

有人对这里发生的事情有什么建议吗?

下面更新

总结 - 在调用 Plot 2 之后的几行中,有一些 R 代码会生成执行错误(未找到变量),之后几行调用 Plot 3。如果代码错误已修复,则 Plot 2被渲染。如果代码错误未修复并且对 Plot 3 的调用被注释掉,则渲染 Plot 2。问题取决于用于存储不同拟合结果的相同变量“拟合”。如果我将每个拟合分配给不同的变量 Plot 2 呈现 OK。

我不明白在成功执行多行代码后所做的更改如何(显然是追溯性地)阻止 Plot 2 呈现。

可重现的例子:

Some text.

```{r setup}
require(mgcv)

mkdata <- function(n=100) {
  x <- rnorm(n) + 5
  y <- x + 0.3 * rnorm(n)
  x[sample(ceiling(n/2), ceiling(n/10))] <- NA
  x <- x^2
  data.frame(x, y)  
} 
```

Example 1
=========

Plot 2 fails to render. (Using the same fit object for each fit.)

```{r example_1}
j0 <- mkdata()
attach(j0)
mx <- min(x, na.rm=TRUE)

fit <- gam(y ~ s(x), data=j0, subset= !is.na(x))
summary(fit)
plot(fit) # plot 1

fit <- gam(y ~ s(sqrt(x)), data=j0, subset= !is.na(x))
summary(fit)
plot(fit) #plot 2

mean(y[is.na(x)]) - mean(y[!is.na(x)]) # means calculation

# recode the missing values
j0$x.na <- is.na(x)
j0$x.c <- ifelse(x.na, mx, x) # ERROR in recode
detach()

attach(j0)
fit <- gam(y ~ s(sqrt(x.c)) + x.na, data=j0) # doesn't run because of error in recode
summary(fit) # this is actually fit 2
plot(fit) # plot 3 (this is actually fit 2)
detach()
```

Example 2
=========

Use separate fit objects for each fit. Plot 2 renders OK.

```{r example_2}
j0 <- mkdata()
attach(j0)
mx <- min(x, na.rm=TRUE)

fit1 <- gam(y ~ s(x), data=j0, subset= !is.na(x))
summary(fit1)
plot(fit1) # plot 1

fit2 <- gam(y ~ s(sqrt(x)), data=j0, subset= !is.na(x))
summary(fit2)
plot(fit2) #plot 2

mean(y[is.na(x)]) - mean(y[!is.na(x)]) # means calculation

# recode the missing values
j0$x.na <- is.na(x)
j0$x.c <- ifelse(x.na, mx, x) # ERROR in recode
detach()

attach(j0)
fit3 <- gam(y ~ s(sqrt(x.c)) + x.na, data=j0) # doesn't run because of error in recode
summary(fit3)
plot(fit3) # plot 3
detach()
```

Example 3
=========

Revert to using the same fit object for each fit. Plot 2 renders because plot 3 is commented out.

```{r example_3}
j0 <- mkdata()
attach(j0)
mx <- min(x, na.rm=TRUE)

fit <- gam(y ~ s(x), data=j0, subset= !is.na(x))
summary(fit)
plot(fit) # plot 1

fit <- gam(y ~ s(sqrt(x)), data=j0, subset= !is.na(x))
summary(fit)
plot(fit) #plot 2

mean(y[is.na(x)]) - mean(y[!is.na(x)]) # means calculation

# recode the missing values
j0$x.na <- is.na(x)
j0$x.c <- ifelse(x.na, mx, x) # ERROR in recode
detach()

attach(j0)
fit <- gam(y ~ s(sqrt(x.c)) + x.na, data=j0)
summary(fit) # this is actually fit 2
# plot(fit) # plot 3 (this is actually fit 2)
detach()
```

Example 4
=========

Plot 2 renders because later recode error is fixed.

```{r example_4}
j0 <- mkdata()
attach(j0)
mx <- min(x, na.rm=TRUE)

fit <- gam(y ~ s(x), data=j0, subset= !is.na(x))
summary(fit)
plot(fit) # plot 1

fit <- gam(y ~ s(sqrt(x)), data=j0, subset= !is.na(x))
summary(fit)
plot(fit) #plot 2

mean(y[is.na(x)]) - mean(y[!is.na(x)]) # means calculation

# recode the missing values
j0$x.na <- is.na(x)
j0$x.c <- ifelse(j0$x.na, mx, x) # error in recode fixed
detach()

attach(j0)
fit <- gam(y ~ s(sqrt(x.c)) + x.na, data=j0)
summary(fit)
plot(fit) # plot 3
detach()
```

日志文件:

> require(knitr); knit('reproduce.Rmd', encoding='UTF-8');
Loading required package: knitr


processing file: reproduce.Rmd
  |......                                                           |   9%
  ordinary text without R code

  |............                                                     |  18%
label: setup
  |..................                                               |  27%
  ordinary text without R code

  |........................                                         |  36%
label: example_1
  |..............................                                   |  45%
  ordinary text without R code

  |...................................                              |  55%
label: example_2
  |.........................................                        |  64%
  ordinary text without R code

  |...............................................                  |  73%
label: example_3
  |.....................................................            |  82%
  ordinary text without R code

  |...........................................................      |  91%
label: example_4
  |.................................................................| 100%
  ordinary text without R code


output file: reproduce.md

[1] "reproduce.md"

【问题讨论】:

  • 请发布一个可重现的示例。您的问题可能是由于您设置了块选项fig.keep,但没有任何这些信息,这纯粹是猜测。
  • 日志是怎么说的?

标签: r plot knitr rstudio r-markdown


【解决方案1】:

您只是attach() 的又一个受害者,尽管人们一直警告不要使用attach()attach() 太容易搞砸了。你在attach(j0) 之后这样做了:

j0$x.na <- is.na(x)
j0$x.c <- ifelse(x.na, mx, x) # ERROR in recode

当然,R 找不到对象x.na,因为它在任何地方都不存在。是的,它现在在j0 中,但除非您分离j0 并重新附加它,否则它不会暴露给R。换句话说,attach() 不会在您向j0 添加更多变量时自动刷新。所以简单的解决方法是:

j0$x.c <- ifelse(j0$x.na, mx, x)

我理解您为什么要使用 attach() —— 您可以避免到处使用尴尬的 j0$ 前缀,但您需要非常小心使用它。除了我提到的问题,detach() 也不好,因为你没有指定要分离哪个环境,默认情况下,搜索路径上的第二个是分离的,不一定你附上了,例如您可能已将其他包加载到搜索路径中。因此,您必须明确:detach('j0')

返回knitr:如果您想知道,我可以解释发生了什么,但首先,您必须确保您的代码在传递给knitr 之前确实有效。随着错误的消除,您观察到的奇怪现象也将消失。

【讨论】:

  • 谢谢亿辉。我想我的问题最终更多地是关于 knitr 中的错误处理。您可以从我的示例中看到,我知道该错误并且知道修复代码块错误后没有出现 knitr 问题。当由 knitr 执行和直接在 R 中执行时,相同的代码块会产生不同的输出。这使得调试 R 代码更加困难,并意味着特定的工作流程(在转移到 knitr 之前在 R 中完全调试)。这表明 knitr 与其执行的代码并不像理想情况下那样孤立。
  • 为了调试,最好设置chunk选项error=FALSE,或者全局设置opts_chunk$set(error=FALSE);然后knitr将在块中发生错误时停止,您将能够使用traceback()等常用方法调试代码
猜你喜欢
  • 2018-02-15
  • 1970-01-01
  • 2021-02-01
  • 1970-01-01
  • 2020-04-14
  • 2021-06-13
  • 2018-04-19
  • 1970-01-01
  • 2020-01-06
相关资源
最近更新 更多