2013-10-10 38 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()這樣的常用方法來調試代碼。 –