Comment cacher le code dans RMarkdown, avec option de le voir

je suis en train d'écrire un RMarkdown document dans lequel j'aimerais ré-exécuter certains morceaux (5 à 9). Il n'y a pas besoin d'afficher ces morceaux à nouveau, donc j'ai envisagé d'utiliser

```{r echo=FALSE}

pour rendre les morceaux de rediffusion invisibles, comme décrit dans une autre question sur le débordement des piles . C'est très bien, et produit les résultats souhaités (meilleur ajustement de la deuxième itération - voir cette solution implémentée ici ).

dans un monde idéal, cependant, le code serait extensible de sorte que l'utilisateur pourrait voir exactement ce qui se passe s'ils veulent à des fins éducatives et de clarté (Par exemple, voir lien vers la solution Greasemonkey ici ) plutôt que caché comme dans mon second exemple rpubs. La solution peut ressembler à quelque chose comme ceci, mais avec une boîte environnante plus courte pour éviter la distraction:

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])

je suis content de la solution echo=F , mais serait encore plus heureux avec un extensible extrait de code.

Edit: tous les exemples RPubs sauf le PREMIER ont maintenant été supprimés, pour éviter d'engorger leur excellent système de publication avec essentiellement le même document.

22
demandé sur Community 2013-01-02 22:38:44

2 réponses

cela a été rendu beaucoup plus facile avec le paquet rmarkdown , qui n'existait pas il y a trois ans. En gros, il suffit d'allumer "code folding": http://rmarkdown.rstudio.com/html_document_format.html#code_folding . Vous n'avez plus à écrire de JavaScript.

29
répondu Yihui Xie 2017-04-06 19:19:37

si vous ajoutez une balise html avant votre code, vous pouvez utiliser des sélecteurs CSS pour faire des choses intelligentes sur des bits de la sortie-markdown passe handily le HTML à travers:

<style>
div.hidecode + pre {display: none}
</style>

<div class="hidecode"></div>
```{r}
summary(cars)
```

voici ma règle de style CSS qui correspond à la première étiquette <pre> après une <div class=hidecode> et la place pour être invisible. Markdown écrit le morceau R avec deux tags <pre> - un pour le R et un pour la sortie, et ce CSS attrape le premier.

Maintenant vous savez comment pour faire correspondre les blocs de code et de sortie dans CSS, vous pouvez faire toutes sortes de choses intelligentes avec eux dans Javascript. Vous pouvez mettre quelque chose dans la balise <div class=hidecode> et Ajouter un événement click qui modifie la visibilité:

<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)
```

la prochaine étape dans la complexité est de faire l'action basculer, mais alors vous pourriez aussi bien utiliser jQuery et obtenir vraiment funky. Ou utilisez cette méthode simple. Faisons - le avec un bouton, mais vous avez aussi besoin d'un div pour obtenir vos crochets dans la commande R PRE bloc, et le parcours devient un peu compliquée:

<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)
```

(Note: je pensais que vous pourriez envelopper des morceaux de R dans <div> tags:

<div class="dosomething">
```{r}
summary(cars) 
``` 
</div>

mais cela échoue - quelqu'un sait pourquoi?)

9
répondu Spacedman 2013-01-02 21:16:46