Используйте цикл для генерации раздела текста в rmarkdown

Мне нужно создать отчет, состоящий из нескольких разделов, все разделы похожи, только с некоторыми различиями в данных. Количество секций также зависит от данных. То, что я в конечном итоге хочу иметь, это что-то вроде этого:

```{r}
  section_names = c("A","B","C")
  section_data = c(13,14,16)
```

# some looping mechanism here with variable i

This is section `r section_names[i]`

This section data is `r section_data[i]`

#more things go here for the section

#end of loop should go here

В результате должен быть один html/document со всеми разделами один за другим.

Можете ли вы указать мне способ создания такого Rmd файла с циклом?

В идеале я бы надеялся увидеть что-то вроде PHP:

<$php for(i=0;i<10;i++) { ?>
   ## some html template + code chunks here
<$php } ?>

Ответ 1

Этот вопрос похож на на этот, хотя он основан на LateX/RNW. Кроме того, этот ответ демонстрирует динамическое создание документа rmarkdown. Однако ни один из вопросов не является точным дубликатом этого.

В принципе, есть два умственных шага:

  • Укажите разметку разметки, необходимую для каждого раздела. Это может быть что-то вроде строк

    ## This is section <section_name>
    Section data is `<section_data>`.
    Additional section text is: <section_text>.
    
  • Напишите код R, который генерирует эту разметку, заменив заполнители соответствующими значениями.

Для шага 2 использование sprintf является естественным кандидатом для объединения статического и динамического текста. Не забудьте использовать параметры chunk results = "asis", чтобы предотвратить knitr от добавления форматирования к вашему выводу и использовать cat (вместо print), чтобы R не добавлял дополнительные данные, такие как кавычки и номера элементов.

Я изменил структуру входных данных немного для ясности (используя data.frame вместо независимых векторов section_names и section_data).

```{r echo = FALSE, results = "asis"}
input <- data.frame(
  name = LETTERS[1:4],
  data = runif(n = 4),
  text = replicate(4, paste(sample(x = LETTERS, size = 100, replace = TRUE), collapse = "")),
  stringsAsFactors = FALSE)

template <- "## This is section %s
Section data is `%0.2f`.
Additional section text is: %s.

" # dont't forget the newline

for (i in seq(nrow(input))) {
  current <- input[i, ]
  cat(sprintf(template, current$name, current$data, current$text))
}
```

Вывод:

Это раздел A

Данные разделов 0.83. Дополнительный текст раздела: PUFTZQFCYJFNENMAAUDPTWIKLBSVKWMJWODFHSPRJRROTVDGNEROBVQPLLMVNPOUUHGVGRPMKAOAOMVYXKMGMUHNYWZGPRAWPYLU.

Это раздел B

Данные разделов 0.49. Дополнительный текст раздела: PFTYCGFSGSMAYSSCZXWLNLDOQEBJYEVSJIYDJPEPSWQBNWJVRUKBTYIUSTOICFKJFEJCWCAYBCQSRTXUDEQLLXCZNPUKNLJIQJXE.

Это раздел C

Данные разделов 0.58. Дополнительный текст раздела: FCJDDDMNLBUSJMCZVSBPYWCKSFJEARBXXFPAGBTKCWKHPEDGYWYTNGLVGQGJAFZRUMNSDCHKTTMGRFNSUZKFLOUGNWHUBNLVMGDB.

Это раздел D

Данные разделов 0.52. Дополнительный текст раздела: YQIXHABFVQUAAYZNWTZXJDISSLTZJJAZOLJMJSXEENFTUOFOTYKDNNUMFDXLJSWZEVDLCLSYCTSMEXFLBVQYRTBEVZLCTEBPUGTT.

Ответ 2

Просто используйте подход, который я использовал в конце концов.

Я написал файл разметки для раздела. подготовил данные для каждого раздела в основном документе и зациклил на все разделы, которые мне нужны, каждый раз вызывая knit_child() с разделом Rmd.

Ответ 3

Я знаю, что уже поздно, но я использовал это в своем коде, чтобы сделать пронумерованные разделы, и это работает.

for (k in 1:length(listcsv)){ #Begin Loop at pdf file one and continue until all have been completed
subsection <- paste("5", k, sep = ".")}

при этом используется номер цикла (k) для создания номера подраздела, а затем вставка его в номер раздела. Это происходит в разделе 5, но вы можете использовать тот же принцип, чтобы сделать разделы и подразделы до бесконечности.