Tables produces in loop are not show in pdf report

I try to create a pdf report using Rmarkdown, but when I try to make a loop in fuction of the Periodo variable, the tables inclusion in params <- list(res1 = medias.F) doesn't work and I dont have an output error as reference. I always have as output the report (test.pdf) without any result table:

My R code is:

    # Packages
    library(tidyverse)
    library(hnp)
    library(multcomp)
    library(rmarkdown)
    
    
    # Open data set 
    df_trats <- read.csv("https://raw.githubusercontent.com/Leprechault/trash/main/data.csv",sep=";")
    df_trats$Tratamento <- as.factor(df_trats$Tratamento)
    str(df_trats )
    names_trat<-unique(df_trats$Tratamento)
    
    
    # Loop for each Periodo variable
    
    res <- NULL
    
    id.tempo <- unique(unique(df_trats$Periodo))
    
    for(i in 1:length(id.tempo)){
      
      print("Período de tempo analisado")
      print(id.tempo[i]) 
      
      df.subset <- df_trats%>%dplyr::filter(Periodo==id.tempo[i])  
      df.subset$Tratamento <- as.factor(df.subset$Tratamento)
      
      # Models
      model1<-glm(Evento~Tratamento, family="binomial", data=df.subset)
      model2<-glm(Evento~Tratamento, family="quasibinomial", data=df.subset)
    
      
      B<-hnp::hnp(model1, print.on = TRUE, plot=FALSE)
      qB<-hnp::hnp(model2, print.on = TRUE, plot=FALSE) 
      
      pB<-B$out/B$total
      pqB<-qB$out/qB$total
      
      tvalues<-as.data.frame(rbind(pB=pB,pqB=pqB))
      choose.model <- rownames(tvalues%>%filter(V1==min(V1)))
      
      
      # Anova
      if(pB == choose.model){
        anova.df.B<-anova(model1, test="Chisq")
        print(anova(model1, test="Chisq"))
      } else(pqB == choose.model)
      anova.df.qB<-anova(model2, test="F")
      print(anova(model2, test="F"))
      #
      
      # Pairwise comparisions
      if(pB == choose.model){
        print("Medias dos tratamentos")
        medias <- df.subset %>% 
          dplyr::group_by(Tratamento) %>% 
          dplyr::summarize(Mortalidade=mean(Evento)*100, EP = (stats::sd(Evento)/sqrt(n()-1))*100)
        Comparacoes<-summary(glht(model1, linfct=mcp(Tratamento="Tukey")))
        (Comparacoes_up<-summary(Comparacoes, test = univariate()))
        pairwise.res.pB <- cld(Comparacoes_up, level=0.05, Letters= c(LETTERS, letters), decreasing=TRUE)
        medias.lcd<-cld(Comparacoes_up, level=0.05, Letters= c(LETTERS, letters), decreasing=TRUE)
        medias.F <- cbind(medias,as.vector(medias.lcd$mcletters$Letters))
        colnames(medias.F)<-c("Tratamento","Mortalidade","EP","Índice")
        print(medias.F)
      } else(pqB == choose.model)
      print("Medias dos tratamentos")
      medias <- df.subset %>% 
        dplyr::group_by(Tratamento) %>% 
        dplyr::summarize(Mortalidade=mean(Evento)*100, EP = (stats::sd(Evento)/sqrt(n()-1))*100)
      Comparacoes<-summary(glht(model2, linfct=mcp(Tratamento="Tukey")))
      (Comparacoes_up<-summary(Comparacoes, test = univariate()))
      pairwise.res.pqB <- cld(Comparacoes_up, level=0.05, Letters= c(LETTERS, letters), decreasing=TRUE)
      medias.lcd<-cld(Comparacoes_up, level=0.05, Letters= c(LETTERS, letters), decreasing=TRUE)
      medias.F <- cbind(medias,as.vector(medias.lcd$mcletters$Letters))
      colnames(medias.F)<-c("Tratamento","Mortalidade","EP","Índice")
      print(medias.F)
      params <- list(res1 = medias.F) # ... whatever you have to send to the report
    rmarkdown::render("test.Rmd",
                        params = params,
                        output_file ="test.pdf",
                      envir = new.env())
                        
    }
    ##
    # <END> -

My test.Rmd is:

    ---
    title:  "Relatório dos tratamentos: `r names_trat`" 
    author: "Vittia" 
    date: "date: `r Sys.Date()`"
    params:
      res1: res1
    output: pdf_document
    ---
    
    
    ```{r setup, include=FALSE}
    knitr::opts_chunk$set(echo = FALSE)

Please any help with it?

Great reprex!

Dividing the issue into pieces, beginning with the code exclusive of the rmd portions, the for loop runs into trouble when attempting to apply dplyr::filter

[1] "Período de tempo analisado"
[1] 24
Error in UseMethod("filter") : 
  no applicable method for 'filter' applied to an object of class "function"

arising from

df %>% dplyr::filter(Periodo == id.tempo[i])

This is because df is not only the name of the user's source object, it is also the name of a built-in function.

> df
function (x, df1, df2, ncp, log = FALSE) 
{
    if (missing(ncp)) 
        .Call(C_df, x, df1, df2, log)
    else .Call(C_dnf, x, df1, df2, ncp, log)
}
<bytecode: 0x56415312ff38>
<environment: namespace:stats>

When two objects (a function is an object, like everything in R) exist in the same namespace one must take precedence and it can be difficult to predict which. The solution is to avoid conflicting names, using DF, Data, df_ or similar.

I'll come back with other pieces.

1 Like

Thanks very much @technocrat, but I changed df by df_trats and the problem are present yet.

Not exactly clear what your problem is.
But I understand your intention is to create a report for every time period.
However you always use the same output name that has no period indication in it ??

Yeh @HanOostdijk!! I don't know if I'm correct, but in my mind despite the output is the same it will be rewrite by loop and this information works like a append=TRUE in the report. In the final pdf document all the tables are included.

This does not work as you expect.

I did try with

R file Leprechault.Rmd

for(i in 1:2) {
  params <- list(res1 = paste("Period", i))
  rmarkdown::render(
    "Leprechault.Rmd",
    params = params,
    output_file = "Leprechault.pdf",
    envir = new.env()
  )
}

Rmd file Leprechault.Rmd

---
title:  "Relatório dos tratamentos: `r names_trat`" 
author: "Vittia" 
date: "date: `r Sys.Date()`"
params:
  res1: res1
output: pdf_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```

## R Markdown


```{r cars}
print(params$res1)
```

and I got the error

Quitting from lines 2-9 (Leprechault.Rmd) 
Error in eval(tryCatch(parse_only(code), error = function(e) { : 
  object 'names_trat' not found

Leaving out this variables from the title

title:  "Relatório dos tratamentos" 

I get pdf output but see in the pdf only the output of the last parameter:
image

Thanks @HanOostdijk, but for me the error is another:

Error in yaml::yaml.load(yaml, handlers = knit_params_handlers(evaluate = evaluate),  : 
  Reader error: invalid trailing UTF-8 octet: #72 at 15

This could be caused by your use of the parameter to pass a data.frame to the Rmd report.
This page (the interface part) suggests that this is not possible

I would suggest you do minimal calculations in the R-script: only determine id.tempo .
Then do the rmarkdown::render with this period indicator as a parameter.
Of course you have to copy/move to the Rmd file the code to read the csv-file, select the period and to create the table you want to report.

You can then avoid the error in the title by Set the document title dynamically.

2 Likes

@Leprechault if there is still an issue after @HanOostdijk comment, can you rework you example by making it minimal example of what you want to do exactly ?

The Rmd example in your first post is probably truncated - it seems incomplete as we don't see where you are using the params

Tables produces in loop are not show in pdf report

Regarding the title, hence I believe the aim of your task, you'll find other question about loop and tables in this forum. Please do search for them, it will point to some recipes and example in the R Markdown cookbook regarding how to mix Markdown content with computed content. Maybe that is what you encounter.

Anyway, we need more information if it is not already solved for you.

1 Like

This topic was automatically closed 42 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.