2013-10-10 58 views
5

我使用不渲染: Ubuntu的12.04 64位, ř3.0.2, RStudio 0.98.312, knitr 1.5, 降价0.6.3, mgcv1.​​7 -27一些情节在Rstudio,knitr,Rmarkdown

我有一个带有多个代码块的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行,那么缺失的图形将被正确渲染。

有没有人有任何建议,这里发生了什么?

更新下面

总结 - 呼叫为剧情2后的几行有生成执行错误(可变未找到)和几行一些R代码里面之后,有一个呼叫为剧情3.如果代码错误是固定的,然后绘制2。如果代码错误是未定义的,并且对绘图3的调用被注释掉,则绘制绘图2。问题取决于用于存储不同拟合结果的相同变量“拟合”。如果我将每个拟合分配给不同的变量,那么曲线2呈现OK。

我不明白在成功执行多行代码之后如何进行更改(显然是追溯性)可以防止绘制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" 
+2

请发布一个可重复的例子。你的问题可能是由于你有大块选项'fig.keep',但没有任何这些信息,这纯粹是猜测。 – mnel

+0

日志说什么? –

回答

9

你是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中,但它不会暴露给R,除非您分开j0并重新附加它。换句话说,attach()不会自动刷新自己,因为您将更多变量添加到j0。所以简单的解决方法是:

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

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

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

+0

谢谢Yihui。我想我的问题最终是关于knitr中的错误处理。你可以从我的例子中看出,我知道这个错误,并且知道当代码块错误得到修复时,knitr问题没有出现。当由knitr执行并直接在R中执行时,同一块代码会产生不同的输出。这使得调试R代码变得更加困难,并且意味着特定的工作流程(在传输到knitr之前在R中完全调试)。它表明knitr并不像它所执行的代码那样孤立,因为它理想上可能是。 –

+1

为了调试的目的,你最好设置chunk选项'error = FALSE',或者全局设置'opts_chunk $ set(error = FALSE)';那么只要在块中发生错误,'knitr'就会停止,你将能够使用像traceback()这样的常用方法来调试代码。 –