Knitr - Как выровнять код и график бок о бок

существует ли простой способ (например, с помощью опции чанка) получить исходный код чанка и график, который он создает, рядом, как на странице 8 (среди прочего) этот документ?

Я попытался использовать out.width="0.5\\textwidth", fig.align='right', благодаря чему график правильно занимает только половину страницы и выравнивается по правому краю, но исходный код отображается поверх него, что является нормальным поведением. Я хотел бы иметь его на левой стороне сюжета.

Спасибо

Образец кода:

<<someplot, out.width="0.5\\textwidth", fig.align='right'>>=
plot(1:10)
@

person Renaud    schedule 14.06.2012    source источник
comment
Эта презентация, скорее всего, была сделана с помощью beamer с использованием среды \columns{}. Вы пытаетесь сделать то же самое с проектором в LaTeX или рендерите через другой движок (обычный LaTeX и т. д.)?   -  person Gavin Simpson    schedule 14.06.2012
comment
@GavinSimpson правильно, я использовал \columns   -  person baptiste    schedule 14.06.2012
comment
в стандартном латексном документе я бы использовал minipage вместо этого   -  person baptiste    schedule 15.06.2012
comment
@baptiste Я думаю, вы можете использовать ссылку выше в качестве ответа на этот вопрос.   -  person Yihui Xie    schedule 15.06.2012
comment
Я только сейчас увидел эти ответы... Спасибо! Yihui есть ли шанс получить эту встроенную функцию? Смогу ли я реализовать это с помощью крючка? Я так понимаю, так как, как я понял, в вязалке все реализовано как крючок, даже встроенные функции :)   -  person Renaud    schedule 27.07.2012


Ответы (3)


Ну, это оказалось сложнее, чем я ожидал.

Что касается LaTeX, пакет adjustbox дает вам отличный контроль над выравниванием бок о бок, как прекрасно продемонстрировано в этом превосходном ответе на tex.stackexchange.com. Таким образом, моя общая стратегия заключалась в том, чтобы обернуть отформатированный, приведенный в порядок, раскрашенный вывод указанного фрагмента R кодом LaTeX, который: (1) помещает его в среду Adjustbox; и (2) включает графический вывод фрагмента в другой среде AdjustBox справа от него. Для этого мне нужно было заменить обработчик вывода чанка knitr по умолчанию на настраиваемый, определенный в разделе (2) чанка <<setup>>= документа.

Раздел (1) из <<setup>>= определяет перехватчик фрагментов, который можно использовать для временной установки любых глобальных параметров R (и, в частности, здесь, options("width")) для каждого фрагмента. см. здесь вопрос и ответ, которые относятся только к этой части этой установки.

Наконец, Раздел (3) определяет «шаблон» вязания, набор из нескольких опций, которые необходимо устанавливать каждый раз, когда необходимо создать параллельный кодовый блок и рисунок. После определения он позволяет пользователю инициировать все необходимые действия, просто набрав opts.label="codefig" в заголовке чанка.

\documentclass{article}

\usepackage{adjustbox}            %% to align tops of minipages
\usepackage[margin=1in]{geometry} %% a bit more text per line

\begin{document}

<<setup, include=FALSE, cache=FALSE>>=
## These two settings control text width in codefig vs. usual code blocks
partWidth <- 45
fullWidth <- 80
options(width = fullWidth)

##  (1) CHUNK HOOK FUNCTION
##   First, to set R's textual output width on a per-chunk basis, we
## need to define a hook function which temporarily resets global R's
## option() settings, just for the current chunk
knit_hooks$set(r.opts=local({
    ropts <- NA
    function(before, options, envir) {
        if (before) {
            ropts <<- options(options$r.opts)
        } else {
            options(ropts)
        }
    }
}))

## (2) OUTPUT HOOK FUNCTION

##   Define a custom output hook function. This function processes _all_
## evaluated chunks, but will return the same output as the usual one,
## UNLESS a 'codefig' argument appeared in the chunk's header.  In that
## case, wrap the usual textual output in LaTeX code placing it in a
## narrower adjustbox environment and setting the graphics that it
## produced in another box beside it.

defaultChunkHook <- environment(knit_hooks[["get"]])$defaults$chunk

codefigChunkHook <- function (x, options) {
        main <- defaultChunkHook(x, options)
        before <-
            "\\vspace{1em}\n
             \\adjustbox{valign=t}{\n
             \\begin{minipage}{.59\\linewidth}\n"
        after <-
            paste("\\end{minipage}}
                   \\hfill
                   \\adjustbox{valign=t}{",
                   paste0("\\includegraphics[width=.4\\linewidth]{figure/",
                           options[["label"]], "-1.pdf}}"), sep="\n")
    ## Was a codefig option supplied in chunk header?
    ## If so, wrap code block and graphical output with needed LaTeX code.
    if (!is.null(options$codefig)) {
      return(sprintf("%s %s %s", before, main, after))
    } else {
      return(main)
    }
}

knit_hooks[["set"]](chunk = codefigChunkHook)


## (3) TEMPLATE
##   codefig=TRUE is just one of several options needed for the
## side-by-side code block and a figure to come out right. Rather
## than typing out each of them in every single chunk header, we
## define a _template_ which bundles them all together. Then we can
## set all of those options simply by typing opts.label="codefig".

opts_template[["set"]](
codefig = list(codefig=TRUE, fig.show = "hide",
               r.opts = list(width=partWidth),
               tidy = TRUE,
               tidy.opts = list(width.cutoff = partWidth)))
@

A chunk without \texttt{opts.label="codefig"} set...
<<A>>=
1:60
@

\texttt{opts.label="codefig"} \emph{is} set for this one

<<B, opts.label="codefig", fig.width=8, cache=FALSE>>=
library(raster)
library(RColorBrewer)

## Create a factor raster with a nice RAT (Rast. Attr. Table)
r <- raster(matrix(sample(1:10, 100, replace=TRUE), ncol=10, nrow=10))
r <- as.factor(r)
rat <- levels(r)[[1]]
rat[["landcover"]] <- as.character(1:10)
levels(r) <- rat

## To get a nice grid...
p <- as(r, "SpatialPolygonsDataFrame")

## Plot it
plot(r, col = brewer.pal("Set3", n=10),
     legend = FALSE, axes = FALSE, box = FALSE)
plot(p, add = TRUE)
text(p, label =  getValues(r))
@

\texttt{opts.label="codefig"} not set, and all settings back to ``normal''.
<<C>>=
lm(mpg ~ cyl + disp + hp + wt + gear, data=mtcars)
@


\end{document}

введите здесь описание изображения

person Josh O'Brien    schedule 30.04.2014
comment
Долго тянул, честно :-) +1 - person Gavin Simpson; 01.05.2014

я вижу 3 возможности

  • для beamer презентаций я бы выбрал также \begin{columns} ... \end{columns}.
  • Если это только один такой сюжет: мини-страницы
  • Здесь я использовал таблицу (код столбца и результат столбца). (Это пример "обычного" переплетения)

Для всех трех параметров фрагмента будет include = FALSE, а график будет «вручную» помещен в нужное место с помощью \includegraphics[]{}.

person cbeleites unhappy with SX    schedule 26.04.2013
comment
Я поддерживаю этот подход. - person Ellis Valentiner; 14.08.2013

Вы можете отобразить текст в «текстовом графике» из пакета PerformanceAnalytics или gplots.

(Небольшой) недостаток: насколько мне известно, подсветка синтаксиса невозможна.

Образец кода:

```{r fig.width=8, fig.height=5, fig.keep = 'last', echo=FALSE}
suppressMessages(library(PerformanceAnalytics))
layout(t(1:2))
textplot('plot(1:10)')
plot(1:10)
```
person cafe876    schedule 29.06.2012