如何在RMarkdown中隐藏代码,并提供查看选项

43

我正在撰写一个RMarkdown 文档,我希望重新运行一些代码块(5到9)。 这些代码块无需再次显示,因此我考虑使用

标签来结束它们。

```{r echo=FALSE}

如另一个stackoverflow问题所述,使重新运行的代码块不可见是可以实现的。这样做很好,并输出所需结果(改进第二次迭代的拟合 - 在这里实现)。

然而,在理想情况下,代码应该是可展开的,以便用户可以在教育和清晰度方面看到发生了什么(例如,参见Greasemonkey解决方案的链接here),而不像我的第二个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
假设你要输出到HTML,你可以使用JavaScript。学习流行的工具集jQuery会很有帮助。这里有一个例子:http://www.w3schools.com/jquery/jquery_hide_show.asp - Brandon Bertelsen
那就这样吧 - 学起来肯定很值得。唯一的缺点是需要深入研究庞大(600行)的HTML文件:http://pastebin.com/WsLt1Hjx。考虑到RMarkdown的目的是将代码减少到最少,希望能在RMarkdown内部找到解决方案。在这种情况下的另一个问题是rpubs似乎不允许直接编辑Rmd文件输出的HTML。 - RobinLovelace
2个回答

78

1
尽管在最初的问答发布时这项技术还不可用,但现在它已经明显成为了最佳答案。谢谢,Yihui! - Nathan
从哪里可以获取2.0版本?install.packages("rmarkdown")只会安装1.4版本。有任何想法吗? - Asymptote
这对于 Slidyioslides 输出格式也适用吗? - igorkf
@igorkf 不,它不会。 - Yihui Xie
@YihuiXie,你认为这个好吗? - igorkf

10

如果在代码之前添加一个HTML标记,您可以使用CSS选择器对输出的部分进行巧妙处理- markdown会方便地将HTML传递:

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

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

这里的CSS样式规则匹配了第一个<div class=hidecode>后面的第一个<pre>标签,并将其设置为不可见。Markdown使用两个<pre>标签来写R块 - 一个用于R代码,一个用于输出结果,而这个CSS捕获了第一个标签。

现在你知道如何在CSS中匹配代码和输出块后,就可以在Javascript中对它们做各种聪明的事情。你可以在<div class=hidecode>标签中加入一些内容,并添加一个点击事件来切换其可见性:

<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 来获取 R 命令 PRE 区块的钩子,遍历会变得有点复杂:

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

(注意:我认为您可以在<div>标签中包装R代码块:

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

但是它失败了 - 有人知道为什么吗?


你需要找出CSS选择器,以便从按钮到达包含代码的块。在我的示例中,R代码位于DIV后面的PRE块中,因此我在CSS中使用+号和一些nextSibling调用。安装Firebug,学习一些JS和CSS。实际上,我没有考虑使用BUTTON标签... - Spacedman
1
请注意,当您有多个带有自己输出块的R行时,我的选择器会失败。如果您在一个块中输出多个内容,它只会隐藏第一个。正在解决中... - Spacedman
这在我的示例中并不是什么大问题:只需注释掉具有输出的命令即可。在R中,您也可以抑制输出。因此,我解决了基本的切换问题,这太棒了:http://rpubs.com/RobinLovelace/3385。最后一个问题非常简单-将默认切换状态设置为隐藏。当然,有一个单个参数可以实现这一点,但无法在谷歌搜索的干草堆中找到它!https://www.google.co.uk/search?q=.toggle+default+hidden - RobinLovelace
这非常依赖于 markdown 转 HTML 过程中的确切输出,可能会因您使用的包版本而有所不同。没有看到您的输出很难确定。 - Spacedman
如果您感兴趣,可以获取原始的Markdown (.md)文件 https://www.dropbox.com/s/rvum7l4viry69zq/microsimulation-eg-new-toggle.md 和HTML https://www.dropbox.com/s/e3kl85linsbee2d/microsimulation-eg-new-toggle.html 文件! - RobinLovelace
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接