2013-10-10 2 views
5

Я использую: Ubuntu 12.04 64-бит, R 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 строк позже в куске, то отсутствующий участок отображается правильно.

У кого-нибудь есть предложения относительно того, что здесь происходит?

UPDATE НИЖЕ

Резюме - Несколько строк после вызова на участок 2 есть некоторый R код, который генерирует ошибку выполнения (переменный не найдено) и несколько линий после этого есть вызов для Заговора 3. Если ошибка кода фиксируется, тогда отображается график 2. Если ошибка кода нефиксирована, а вызов Plot 3 закомментирован, то отображается график 2. Проблема зависит от той же переменной «fit», которая используется для хранения результатов разных приемов. Если я присваиваю каждую поправку другой переменной, то Plot 2 отображает ОК.

Я не понимаю, как изменения, сделанные после нескольких строк успешно выполненного кода, могут (по-видимому, ретроспективно) помешать 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" 
+2

Пожалуйста, разместите воспроизводимый пример. Вероятно, ваша проблема связана с тем, что у вас есть опция chunk option 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 и снова подключите его. Другими словами, не обновляется автоматически при добавлении дополнительных переменных в j0. Таким образом, простое исправление:

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

Я понимаю, почему вы хотите использовать attach() - вы можете избежать неловкой j0$ префикс везде, но вы должны быть очень осторожны с ним.Помимо проблемы, о которой я упоминал, detach() также плохой, потому что вы не указали, какую среду отключить, а по умолчанию отключен второй на пути поиска, который равен , а не обязательно тот, который вы подключили, например. вы могли бы загрузить другие пакеты на путь поиска. Поэтому вы должны быть явными: detach('j0').

Назад к knitr: Я могу объяснить, что происходит, если вы хотите знать, но прежде всего, вы должны убедиться, что ваш код действительно работает, прежде чем передавать его на knitr. Поскольку ошибка устранена, нечетное явление, которое вы наблюдаете, также исчезнет.

+0

Спасибо Yihui. Я думаю, мой вопрос в конечном итоге был больше об обработке ошибок в knitr. Из моего примера видно, что я знал об ошибке и знал, что проблема с книгой не появилась, когда была исправлена ​​ошибка блока кода. Один и тот же кусок кода создает различный вывод при исполнении knitr и при выполнении непосредственно в R. Это затрудняет отладку кода R и подразумевает конкретный рабочий процесс (полностью отлаживается в R перед передачей в knitr). Это говорит о том, что knitr не так изолирован от кода, который он выполняет, поскольку он идеально может быть. –

+1

Для целей отладки лучше установить параметр chunk 'error = FALSE' или установить глобально' opts_chunk $ set (error = FALSE) '; то 'knitr' будет останавливаться всякий раз, когда возникает ошибка в кусках, и вы сможете отлаживать код, используя обычные методы, такие как' traceback() ' –

Смежные вопросы