Search code examples
rlatexmarkdown

R - Data type error after the loop creating markdown completes several times


This code cycles through the dataframe creating a page for a latex markdown file with a page for each column. It goes through several columns before hanging up on one with this data type error.

The column it hangs up on is all null values because a student turned in no assignments

Why does it successfully complete the loop several times and then get hung up on the data type error with all null values? And how can I prevent this from happening?

Error in `[<-`:
! Assigned data `list("-", "-", "-")` must be compatible with existing data.
ℹ Error occurred for column `Points`.
Caused by error in `vec_assign()`:
! Can't convert <character> to <integer>.
Backtrace:
 1. base::`[<-`(`*tmp*`, nrow(currentreport) + 1, , value = `<list>`)
 2. tibble:::`[<-.tbl_df`(`*tmp*`, nrow(currentreport) + 1, , value = `<list>`)
 3. tibble:::tbl_subassign(x, i, j, value, i_arg, j_arg, substitute(value))
 4. tibble:::tbl_subassign_row(xo, i, value, i_arg, value_arg, call)
 6. tibble:::vectbl_assign(x[[j]], i, recycled_value[[j]])
 7. vctrs::vec_assign(x, i, value)
markdown_file <- "output_table.md" 

sink(markdown_file)

for (i in 1:n) {
  cat("\n\n\\pagebreak\n")
  currentname <- df2[1, paste("Student", i, sep = " ")]
  currentreport <- df2[df2[paste("Student", i, sep = " ")] == 1, c(1, 2, 3)]
  deduct <- sum(currentreport$Points)
  grade <- 100 + deduct
  cat('\n')  
  writeLines(paste("\\begin{center}\n\\section*{", title, "}\n\\end{center}\n", sep = '')) 
  writeLines(paste("\\begin{center}\n\\textbf{\\large Name: ", currentname, "}\n\\end{center}\n", sep = '')) 
  writeLines(paste("\\begin{center}\n\\textbf{\\large Grade: ", grade, "}\n\\end{center}\n", sep = '')) 
  cat('\n\n')  
  cat('&nbsp;')
  if (nrow(currentreport) < 1) {
    currentreport[nrow(currentreport) + 1, ] <- list('-', '-', '-')
  }
  currentreport[nrow(currentreport) + 1, ] <- list(NA, "Total points deducted", deduct)   
  currentreport[nrow(currentreport) + 1, ] <- list(NA, "Grade", grade)
  table <- xtable(currentreport, align = "lclc")
  print(table, hline.after = c(-1, 0, nrow(currentreport) - 2, nrow(currentreport)), 
        comment = F, include.rownames = FALSE, digits = 0, size = 'large')

  cat('\n') 
}

sink()

Solution

  • The error was because it was attempting to sum a column with no values. The code below checks each column for non-null values instead and then if there are no non-null values, gives the grade a zero, but if there are any non-null computes as normal.

    markdown_file <- "output_table.tex"  
    sink(markdown_file)
    
    for (i in 1:n) {
      cat("\n\n\\pagebreak\n")
      currentname <- df2[1, paste("Student", i, sep = " ")]
      currentreport <- df2[df2[paste("Student", i, sep = " ")] == 1, c(1, 2, 3)]
      
      if (sum(!is.na(currentreport$Points)) == 0) {
        cat('\n')  
        writeLines(paste("\\begin{center}\n\\section*{", title, "}\n\\end{center}\n", sep = '')) 
        writeLines(paste("\\begin{center}\n\\textbf{\\large Name: ", currentname, "}\n\\end{center}\n", sep = '')) 
        writeLines(paste("\\begin{center}\n\\textbf{\\large Grade: 0 }\n\\end{center}\n", sep = '')) 
        cat('\n\n')  
        cat('&nbsp;')
        currentreport <- data.frame(Question = "-", Description = "-", Points = "-")
      } else {
        deduct <- sum(currentreport$Points)
        grade <- 100 + deduct
        
        cat('\n')  
        writeLines(paste("\\begin{center}\n\\section*{", title, "}\n\\end{center}\n", sep = '')) 
        writeLines(paste("\\begin{center}\n\\textbf{\\large Name: ", currentname, "}\n\\end{center}\n", sep = '')) 
        writeLines(paste("\\begin{center}\n\\textbf{\\large Grade: ", grade, "}\n\\end{center}\n", sep = '')) 
        cat('\n\n')  
        
        currentreport[nrow(currentreport) + 1, ] <- list(NA, "Total points deducted", deduct)   
        currentreport[nrow(currentreport) + 1, ] <- list(NA, "Grade", grade)
      }
      
      table <- xtable(currentreport, align = "lclc")
      print(table, hline.after = c(-1, 0, nrow(currentreport) - 2, nrow(currentreport)), 
            comment = FALSE, include.rownames = FALSE, digits = 0, size = 'large')
    
      cat('\n') 
    }
    
    sink()