Как скрыть код в RMarkdown, с возможностью увидеть его
Я пишу RMarkdown документ, в котором я хотел бы повторно запустить некоторые куски (от 5 до 9).
Нет необходимости снова отображать эти куски, поэтому я решил использовать
```{r echo=FALSE}
чтобы сделать повторные куски невидимыми, как описано в другом вопросе qaru.site/info/151291/.... Это хорошо и выводит желаемые результаты (улучшенная подгонка второй итерации - см. Это решение реализовано здесь).
Тем не менее, в идеальном мире код будет расширяться, чтобы пользователь мог точно видеть, что происходит, если они хотят в образовательных целях и ясности (например, см. ссылку на решение Greasemonkey
здесь), а не скрыто, как в моем втором примере rpubs. Решение может выглядеть примерно так, но с более коротким окружением, чтобы избежать отвлечения:
for (i in 1:nrow(all.msim)){ # Loop creating aggregate values (to be repeated later)
USd.agg[i,] <- colSums(USd.cat * weights0[,i])
}
for (j in 1:nrow(all.msim)){
weights1[which(USd$age <= 30),j] <- all.msim[j,1] /USd.agg[j,1]
weights1[which(USd$age >= 31 & USd$age <= 50),j] <- all.msim[j,2] /USd.agg[j,2]
weights1[which(USd$age >= 51),j] <- all.msim[j,3] /USd.agg[j,3] ##
}
# Aggregate the results for each zone
for (i in 1:nrow(all.msim)){
USd.agg1[i,] <- colSums(USd.cat * weights0[,i] * weights1[,i])
}
# Test results
for (j in 1:nrow(all.msim)){
weights2[which(USd$sex == "m"),j] <- all.msim[j,4] /USd.agg1[j,4]
weights2[which(USd$sex == "f"),j] <- all.msim[j,5] /USd.agg1[j,5]
}
for (i in 1:nrow(all.msim)){
USd.agg2[i,] <- colSums(USd.cat * weights0[,i] * weights1[,i] * weights2[,i])
}
for (j in 1:nrow(all.msim)){
weights3[which(USd$mode == "bicycle"),j] <- all.msim[j,6] /USd.agg2[j,6]
weights3[which(USd$mode == "bus"),j] <- all.msim[j,7] /USd.agg2[j,7]
weights3[which(USd$mode == "car.d"),j] <- all.msim[j,8] /USd.agg2[j,8]
weights3[which(USd$mode == "car.p"),j] <- all.msim[j,9] /USd.agg2[j,9]
weights3[which(USd$mode == "walk"),j] <- all.msim[j,10] /USd.agg2[j,10]
}
weights4 <- weights0 * weights1 * weights2 * weights3
for (i in 1:nrow(all.msim)){
USd.agg3[i,] <- colSums(USd.cat * weights4[,i])
}
# Test results
plot(as.vector(as.matrix(all.msim)), as.vector(as.matrix(USd.agg3)),
xlab = "Constraints", ylab = "Model output")
abline(a=0, b=1)
cor(as.vector(as.matrix(all.msim)), as.vector(as.matrix(USd.agg3)))
#rowSums(USd.agg3[,1:3]) # The total population modelled for each zone, constraint 1
#rowSums(USd.agg3[,4:5])
#rowSums(USd.agg3[,6:10])
Я доволен решением echo=F
, но был бы еще счастливее с расширяемым фрагментом кода.
Изменить: все примеры RPubs, кроме первого, теперь удалены, чтобы не засорить их отличную систему публикации с помощью того же документа.
Ответы
Ответ 1
Это стало намного проще с пакетом rmarkdown, который не существовал три года назад. В основном вы просто включаете "сворачивание кода": http://rmarkdown.rstudio.com/html_document_format.html#code_folding. Вам больше не нужно писать JavaScript.
Ответ 2
Если вы добавите тег html перед своим кодом, вы можете использовать селекторы CSS, чтобы делать умные вещи в битах вывода - уценка удобно передает HTML через:
<style>
div.hidecode + pre {display: none}
</style>
<div class="hidecode"></div>
```{r}
summary(cars)
```
Здесь мое правило стиля CSS совпадает с первым тегом <pre>
после <div class=hidecode>
и устанавливает его невидимость. Markdown записывает фрагмент R с двумя тегами <pre>
- один для R и один для вывода, и этот CSS улавливает первый.
Теперь вы знаете, как сопоставить код и выходные блоки в CSS, вы можете делать с ними всевозможные умные вещи в Javascript. Вы можете поместить что-то в тег <div class=hidecode>
и добавить событие click, которое переключает видимость:
<style>
div.hidecode + pre {display: none}
</style>
<script>
doclick=function(e){
e.nextSibling.nextSibling.style.display="block";
}
</script>
<div class="hidecode" onclick="doclick(this);">[Show Code]</div>
```{r}
summary(cars)
```
Следующий шаг в сложности - заставить действие переключиться, но тогда вы также можете использовать jQuery
и получить настоящий фанк. Или используйте этот простой метод. Позвольте сделать это с помощью кнопки, но вам также нужен div, чтобы получить ваши крючки в блок PRE команды R, и обход становится немного сложным:
<style>
div.hideme + pre {display: none}
</style>
<script>
doclick=function(e){
code = e.parentNode.nextSibling.nextSibling.nextSibling.nextSibling
if(code.style.display=="block"){
code.style.display='none';
e.textContent="Show Code"
}else{
code.style.display="block";
e.textContent="Hide Code"
}
}
</script>
<button class="hidecode" onclick="doclick(this);">Show Code</button>
<div class="hideme"></div>
```{r}
summary(cars)
```
(Примечание: я думал, что вы можете обернуть фрагменты R в тегах <div>
:
<div class="dosomething">
```{r}
summary(cars)
```
</div>
но это не удается - кто-нибудь знает почему?)