2017-02-13 5 views
2

文書では、1つのチャンク内に複数のプロットをプロットしています。私は各プロットの高さを縦軸のカテゴリ数に比例させたいと思っています。 this SO answerに基づいて、knit_expandを使用してこれを実行して、プログラムごとにチャンクオプションを設定して各プロットの新しいチャンクを作成しようとしています。knitr:knit_expandを使用して、チャンク内でプログラムでプロットの高さを変更するときのチャンクラベルの重複エラー

サンプル再現可能なデータとコードを含むドキュメントが以下に貼り付けられます。 kexpand関数は、プロットごとに新しいチャンクを作成するものです。最後のチャンクのforループで関数を実行します。 forループは、サンプルデータのdeptの各レベルに1つずつ、3つのプロットを作成します。しかし、私は(試みには)文書を編むとき、私は次のエラーを取得する:

Line 23 Error in parse_block(g[-1], g[1], params.src) : duplicate label 'English' Calls: ... process_file -> split_file -> lapply -> FUN -> parse_block Execution halted

これは私が動的チャンクオプションを変更しようとしたのは初めてであり、私はチャンクのラベルがあるかどうかはわかりませんdeptの各レベルはknit_expandに一度しか入っていないため、重複しています。私はthis SO questionknitの代わりにknit_childの代わりにkexpandの機能を使ってみましたが、同じエラーが出ました。

(1)重複したラベルのエラーを回避して文書を適切に編成するにはどうすればよいですか。(2)正しい方法を考えているか、動的に変更する方がいいですか?ループ内にプロットやテーブルを作成する際のチャンクオプション小さな修正(kexpandの定義を確認してください)で

--- 
title: "Untitled" 
author: "eipi10" 
date: "February 12, 2017" 
output: pdf_document 
--- 

```{r setup, include=FALSE} 
knitr::opts_knit$set(progress = FALSE, verbose = FALSE) 
knitr::opts_chunk$set(echo = FALSE, message=FALSE, warning=FALSE) 

library(tidyverse) 
library(scales) 
library(knitr) 
``` 

```{r} 
# Adapted from https://stackoverflow.com/a/27234462/496488 
kexpand <- function(ht, cap, plot) { 
    cat(
    knit(
     text=knit_expand(
     text=sprintf("```{r %s, fig.height=%s, fig.cap='%s'}\n%s\n```", cap, ht, cap, plot) 
    ))) 
} 
``` 

```{r data} 
df = structure(list(dept = c("English", "English", "English", "English", 
"English", "English", "English", "English", "English", "English", 
"English", "English", "English", "English", "English", "Biology", 
"Biology", "Biology", "Biology", "Biology", "Biology", "Government", 
"Government"), tot_enrl = c(114, 349, 325, 393, 415, 401, 166, 
117, 302, 267, 256, 224, 481, 295, 122, 410, 478, 116, 278, 279, 
238, 142, 145), course = c("ENGL 1", "ENGL 10M", "ENGL 11M", 
"ENGL 16", "ENGL 1X", "ENGL 20M", "ENGL 3", "ENGL 30A", "ENGL 40A", 
"ENGL 40B", "ENGL 50A", "ENGL 50B", "ENGL 5M", "ENGL 60", "ENGL 65", 
"BIO 15L", "BIO 2", "BIO 30", "BIO 39", "BIO 7", "BIO 9", "GOVT 10", 
"GOVT 1H")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-23L), .Names = c("dept", "tot_enrl", "course")) 
``` 

```{r results="asis"} 
height.unit = 0.2 

for (d in unique(df$dept)) { 

    .pl = ggplot(df[df$dept==d, ], aes(tot_enrl, reorder(course,tot_enrl))) + geom_point() 

    ht = height.unit * length(unique(df$course[df$dept==d])) + 1 

    kexpand(ht=ht, cap=d, plot=.pl) 
} 
``` 

答えて

1

はここに正しいアプローチであるが、実装します適合from rawr's anserは...奇妙です(IMHO)。

knit_expand(text=sprintf("```{r %s, fig.height=%s, fig.cap='%s'}\n%s\n```", cap, ht, cap, plot)) 

これはr-bloggers.com post RAWRのソリューションのコンテキストで動作する可能性が基づいているが、一般的に、これはknit_expandが使用されることを想定している方法ではありません。

これはあなたのソリューションの中核です。

  • knit_expandは、独自のテンプレートを解決します。sprintfを使用すると、ここでは無意味です。 ?knit_expand

    This function expands a template based on the R expressions in {{}} (this tag can be customized by the delim argument). These expressions are extracted, evaluated and replaced by their values in the original template.

  • の代わりに、動的に生成されたチャンクにコードを注入することから、あなたは/ rawrが.plggplot戻り値を注入されています。

質問(とunique(df$dept)[1]からdセット)からのコードで定義された変数と

knit_expand(text=sprintf("```{r %s, fig.height=%s, fig.cap='%s'}\n%s\n```", d, ht, d, .pl)) 

を実行してみてください。.plcharacterに変換されているため、これはチャンク(および多くのゴミ)に展開されます。 「重複ラベル」エラーは、同じラベルを持つこれらのチャンクのすべてに起因します。生成されたチャンクknit_expandのテンプレート機能を使用し、内部プロットを生成するコードを移動:

--- 
output: pdf_document 
--- 

```{r setup, include=FALSE} 
knitr::opts_knit$set(progress = FALSE, verbose = FALSE) 
knitr::opts_chunk$set(echo = FALSE, message=FALSE, warning=FALSE) 

library(ggplot2) 
library(knitr) 
``` 

```{r} 
kexpand <- function(height, caption, d) { 

    cat(
    knit(text=knit_expand(
     text=(
"```{r {{caption}}, fig.height={{height}}, fig.cap='{{caption}}'} 
ggplot(df[df$dept=='{{d}}', ], aes(tot_enrl, reorder(course,tot_enrl))) + geom_point() 
```"), 
     caption = caption, 
     height = height, 
     d = d))) 
} 
``` 

```{r data} 
df = structure(list(dept = c("English", "English", "English", "English", 
    "English", "English", "English", "English", "English", "English", 
    "English", "English", "English", "English", "English", "Biology", 
    "Biology", "Biology", "Biology", "Biology", "Biology", "Government", 
    "Government"), tot_enrl = c(114, 349, 325, 393, 415, 401, 166, 
    117, 302, 267, 256, 224, 481, 295, 122, 410, 478, 116, 278, 279, 
    238, 142, 145), course = c("ENGL 1", "ENGL 10M", "ENGL 11M", 
    "ENGL 16", "ENGL 1X", "ENGL 20M", "ENGL 3", "ENGL 30A", "ENGL 40A", 
    "ENGL 40B", "ENGL 50A", "ENGL 50B", "ENGL 5M", "ENGL 60", "ENGL 65", 
    "BIO 15L", "BIO 2", "BIO 30", "BIO 39", "BIO 7", "BIO 9", "GOVT 10", 
    "GOVT 1H")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
    -23L), .Names = c("dept", "tot_enrl", "course")) 
``` 

```{r results="asis"} 
height.unit <- 0.2 

for (d in unique(df$dept)) { 
    ht <- height.unit * length(unique(df$course[df$dept==d])) + 1 

    kexpand(height=ht, caption=d, d = d) 
} 
``` 

正解はthis answerの最後の部分に類似していなければなりません

2

、あなたの例のコードは、私の作品:

knit_expandを使用して
--- 
title: "Untitled" 
author: "eipi10" 
date: "February 12, 2017" 
output: pdf_document 
--- 

```{r setup, include=FALSE} 
knitr::opts_knit$set(progress = FALSE, verbose = FALSE) 
knitr::opts_chunk$set(echo = FALSE, message=FALSE, warning=FALSE) 

library(tidyverse) 
library(scales) 
library(knitr) 
``` 

```{r} 
# Adapted from http://stackoverflow.com/a/27234462/496488 
kexpand <- function(ht, cap) { 
    cat(
    knit(
     text=knit_expand(
     text=sprintf("```{r %s, fig.height=%s, fig.cap='%s'}\n .pl \n```", cap, ht, cap) 
    ))) 
} 
``` 

```{r data} 
df = structure(list(dept = c("English", "English", "English", "English", 
"English", "English", "English", "English", "English", "English", 
"English", "English", "English", "English", "English", "Biology", 
"Biology", "Biology", "Biology", "Biology", "Biology", "Government", 
"Government"), tot_enrl = c(114, 349, 325, 393, 415, 401, 166, 
117, 302, 267, 256, 224, 481, 295, 122, 410, 478, 116, 278, 279, 
238, 142, 145), course = c("ENGL 1", "ENGL 10M", "ENGL 11M", 
"ENGL 16", "ENGL 1X", "ENGL 20M", "ENGL 3", "ENGL 30A", "ENGL 40A", 
"ENGL 40B", "ENGL 50A", "ENGL 50B", "ENGL 5M", "ENGL 60", "ENGL 65", 
"BIO 15L", "BIO 2", "BIO 30", "BIO 39", "BIO 7", "BIO 9", "GOVT 10", 
"GOVT 1H")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-23L), .Names = c("dept", "tot_enrl", "course")) 
``` 

```{r results="asis"} 

height.unit = 0.2 

for (d in unique(df$dept)) { 

    .pl = ggplot(df[df$dept==d, ], aes(tot_enrl, reorder(course,tot_enrl))) + geom_point() 

    ht = height.unit * length(unique(df$course[df$dept==d])) + 1 

    kexpand(ht=ht, cap=d) 
} 
``` 

enter image description here

関連する問題