R Markdown embedding a function into a simple tabl

2019-07-23 19:54发布

问题:

I'm new to R and I'm really liking the flexibility of R Markdown to create reports.

My problem is that I want to use a random number generating function I've created my tables. I want simple tables to include string headers and the following function:

> ran<-function(x){
+     x<-runif(n=1, min=13.5,max=15.5)
+     round(x, digits=2)}.

It won't allow me to create a table using this method?

```{r}
String   |String   |String
-------|------|------
ran(x)|ran(x)|ran(x)
```

My ultimate goal is to create practice worksheets with simple statistics that will be different but within a bounded integer range - so I can ask follow-up questions with some idea of the mean, median etc.

Any help would be greatly appreciated.

回答1:

Perhaps you should read up on both how to build working R code and how to code up Rmd files since your function doesn't work and there are a few places in the R Markdown docs that show how to do this:

---
output: html_document
---

```{r echo=FALSE}
ran <- function(x) { 
  runif(n=1, min=13.5, max=15.5) + round(x, digits=2)
}
```

One        |Two          |Three
-----------|-------------|-----------
`r ran(2)` | `r ran(3)`  | `r ran(4)`
`r ran(2)` | `r ran(3)`  | `r ran(4)`
`r ran(2)` | `r ran(3)`  | `r ran(4)`
`r ran(2)` | `r ran(3)`  | `r ran(4)`

generates:

Also, neither SO nor RStudio charges extra for spaces in code blocks. It'd be good to show students good code style while you're layin' down stats tracks.



回答2:

Here is an approach that automates much of the report generation and reduces the amount of code you need to type. For starters, you can turn this into a parameterized report, which would make it easier to create worksheets using different values of x. Here's an example:

In your rmarkdown document you would declare parameters x and n in the yaml header. n is the number of random values you want to produce for each value of x. The x and n values in the yaml header are just the defaults knitr uses if no other values are input when you render the report:

---
output: html_document
params: 
  x: !r c(1,5,10)
  n: 10
---

Then, in the same rmarkdown document you would have the text and code for your worksheet. You access the parameters x and n with params$x and params$n, respectively.

For example, the rest of the rmarkdown document could look like the code below. We put x into a list called x_vals with named elements, so that the resulting column names in the output will be the names of the list elements. We feed that list to sapply to get a column of n random values for each value of x. The whole sapply statement is wrapped in kable, which produces a table in rmarkdown format.

```{r, include=FALSE}
library(knitr)
```

```{r, echo=FALSE}
# Create a named list of the x values that we passed into this document
x_vals = as.list(setNames(params$x, paste0("x=", params$x)))

kable(sapply(x_vals, function(i) round(runif(params$n, 13.5, 15.5) + i, 2)))
```

You can now click the "knit" button and it will produce a table using the default parameter values:

If instead you want to use different values for x and/or n, open a separate R script file and type the following:

rmarkdown::render("Worksheet.Rmd", 
                  params = list(x = c(2,4,6,8), 
                                n = 5),
                  output_file="Worksheet.html")

In the code above, the render function compiles the rmarkdown document we just created, but with new x and n values, and saves the output to a file called Worksheet.html. (I've assumed that we've saved the rmarkdown document to a file called Worksheet.Rmd.) Here's what the output looks like:

You can also, of course, add parameters for the lower and upper limits of the runif function, rather than hard-coding them as 13.5 and 15.5.

If you want to create several worksheets, each with different x values, you can put render in a loop:

df = expand.grid(1:3,5:6,10:11)

for (i in 1:nrow(df)) {
  rmarkdown::render("Worksheet.Rmd", 
                    params = list(x=unlist(df[i,]), n=10),
                    output_file=paste0(paste(unlist(df[i,]),collapse="_"),".html"))
}