How to hide code in RMarkdown, with option to see it

匿名 (未验证) 提交于 2019-12-03 02:14:01

问题:

I'm writing an RMarkdown document in which I'd like to re-run some chunks (5 to 9). There's no need to display these chunks again, so I considered using

```{r echo=FALSE} 

to make the rerun chunks invisible, as described in another stackoverflow question. This is fine, and outputs the desired results (improved fit of second iteration - see this solution implemented here).

In an ideal world, however, the code would be expandable so the user could see exactly what's going on if they want to for educational purposes and clarity (e.g. see link to Greasemonkey solution here) rather than hidden as in my second rpubs example. The solution may look something like this, but with a shorter surrounding box to avoid 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]) 

I'm happy with the echo=F solution, but would be even happier with an expandable code snippet one.

Edit: all RPubs examples except the first have now been removed, to avoid clogging their excellent publication system with essentially the same document.

回答1:

This has been made much easier with the rmarkdown package, which did not exist three years ago. Basically you just turn on "code folding": http://rmarkdown.rstudio.com/html_document_format.html#code_folding. You no longer have to write any JavaScript.



回答2:

If you add an html tag before your code you can use CSS selectors to do clever things to bits of the output - markdown handily passes the HTML through:

<style> div.hidecode + pre {display: none} </style>  <div class="hidecode"></div> ```{r} summary(cars) ``` 

Here my CSS style rule matches the first <pre> tag after a <div class=hidecode> and sets it to be invisible. Markdown writes the R chunk with two <pre> tags - one for the R and one for the output, and this CSS catches the first one.

Now you know how to match the code and output blocks in CSS, you can do all sorts of clever things with them in Javascript. You could put something in the <div class=hidecode> tag and add a click event that toggles the visibility:

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

The next step in complexity is to make the action toggle, but then you might as well use jQuery and get real funky. Or use this simple method. Let's do it with a button, but you also need a div to get your hooks into the R command PRE block, and the traversal gets a bit complicated:

<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: I thought you could wrap R chunks in <div> tags:

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

but that fails - anyone know why?)



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!