1
votes

I'm working with the WRS2 package and there are cases where it'll output its analysis (bwtrim) into a list with a special class of the analysis type class = "bwtrim". I can't as.data.frame() it, but I found that there is a custom print method called print.bwtrim associated with it.

As an example let's say this is the output: bwtrim.out <- bwtrim(...). When I run the analysis output in an Rmarkdown chunk, it seems to "steal" part of the text output and make it into a dataframe.

So here's my question, how can I either access print.bwtrim or how does R markdown automatically format certain outputs into dataframes? Because I'd like to take this outputted dataframe and use it for other purposes.


Update: Here is a minimally working example -- put the following in a chunk in Rmd file."

```{r}
library(WRS2)


df <-
  data.frame(
    subject = rep(c(1:100), each = 2),
    group = rep(c("treatment", "control"), each = 2),
    timepoint = rep(c("pre", "post"), times = 2),
    dv = rnorm(200, mean = 2)
  )

analysis <- WRS2::bwtrim(dv ~ group * timepoint,
                         id = subject,
                         data = df,
                         tr = .2)

analysis
```

With this, a data.frame automatically shows up in the chunk afterwards and it shows all the values very nicely. My main question is how can I get this data.frame for my own uses. Because if you do str(analysis), you see that it's a list. If you do class(analysis) you get "bwtrim". if you do methods(class = "bwtrim"), you get the print method. And methods(print) will have a line that says print.bwtrim*. But I can't seem to figure out how to call print.bwtrim myself.


Regarding what Rmarkdown is doing, compare the following

If you run this in a chunk, it actually steals the data.frame part and puts it into a separate figure.

```{r}
capture.output(analysis)
```

However, if you run the same line in the console, the entire output comes out properly. What's also interesting is that if you try to assign it to another object, the output will be stolen before it can be assigned.

Compare x when you run the following in either a chunk or the console.

```{r}
x<-capture.output(analysis)
```

This is what I get from the chunk approach when I call x

[1] "Call:"                                                        
[2] "WRS2::bwtrim(formula = dv ~ group * timepoint, id = subject, "
[3] "    data = df, tr = 0.2)"                                     
[4] ""                                                             
[5] "" 

This is what I get when I do it all in the console

[1] "Call:"                                                        
[2] "WRS2::bwtrim(formula = dv ~ group * timepoint, id = subject, "
[3] "    data = df, tr = 0.2)"                                     
[4] ""                                                             
[5] "                 value df1     df2 p.value"                   
[6] "group           1.0397   1 56.2774  0.3123"                   
[7] "timepoint       0.0001   1 57.8269  0.9904"                   
[8] "group:timepoint 0.5316   1 57.8269  0.4689"                   
[9] "" 

My question is what can I call whatever Rstudio/Rmarkdown is doing to make data.frames, so that I can have an easy data.frame myself?


Update 2: This is probably not a bug, as discussed here https://github.com/rstudio/rmarkdown/issues/1150.


Update 3: You can access the method by using WRS2:::bwtrim(analysis), though I'm still interested in what Rmarkdown is doing.


Update 4: It might not be the case that Rmarkdown is stealing the output and automatically making dataframes from it, as you can see when you call x after you've already captured the output. Looking at WRS2:::print.bwtrim, it prints a dataframe that it creates, which I'm guessing Rmarkdown recognizes then formats it out.

See below for the print.bwtrim.

function (x, ...) 
{
    cat("Call:\n")
    print(x$call)
    cat("\n")
    dfx <- data.frame(value = c(x$Qa, x$Qb, x$Qab), df1 = c(x$A.df[1], 
        x$B.df[1], x$AB.df[1]), df2 = c(x$A.df[2], x$B.df[2], 
        x$AB.df[2]), p.value = c(x$A.p.value, x$B.p.value, x$AB.p.value))
    rownames(dfx) <- c(x$varnames[2], x$varnames[3], paste0(x$varnames[2], 
        ":", x$varnames[3]))
    dfx <- round(dfx, 4)
    print(dfx)
    cat("\n")
}
<bytecode: 0x000001f587dc6078>
<environment: namespace:WRS2>
1
Are you using WRS2 or WRSS? There doesn't seem to be a package called WRS on CRANEmily Kothe
could we have a minimal reproducible example please?Ben Bolker
@EmilyKothe My bad, it was WRS2.NAccumbens
@BenBolker I've updated it nowNAccumbens
Are you looking for a general solution or something just for this function in WRS2?Emily Kothe

1 Answers

0
votes

In R Markdown documents, automatic printing is done by knitr::knit_print rather than print. I don't think there's a knit_print.bwtrim method defined, so it will use the default method, which is defined as

function (x, ..., inline = FALSE) 
{
    if (inline) 
        x
    else normal_print(x)
}

and normal_print will call print().

You are asking why the output is different. I don't see that when I knit the document to html_document, but I do see it with html_notebook. I don't know the details of what is being done, but if you look at https://rmarkdown.rstudio.com/r_notebook_format.html you can see a discussion of "output source functions", which manipulate chunks to produce different output.

The fancy output you're seeing looks a lot like what knitr::knit_print does for a dataframe, so maybe html_notebook is substituting that in place of print.