Search code examples
rgt

How to use gt::text_transform inside a loop


I would like to add values under the cell content inside of a for loop (to iterate through my table. So consider this example:

library(dplyr)
library(gt)

df <- as.data.frame(matrix(NA, nrow = 3, ncol = 3))
tab <- gt(df)
for (i in 1:3) {
    tab <- tab %>%
        text_transform(locations = cells_body(
            columns = all_of(i),
            rows = all_of(i)
        ), fn = function(x) {
            paste0(x, "<br>", i)
        })
}
tab

Now tab looks like this:

enter image description here

This is strange, the elements added on the diagonal are identical, however. I would expect them to be 1,2, and 3 respectively.

We can achieve the desired result by avoiding the for loop:

tab <- gt(df)

tab <- tab %>%
    text_transform(locations = cells_body(
        columns = all_of(1),
        rows = all_of(1)
    ), fn = function(x) {
        paste0(x, "<br>", 1)
    })

tab <- tab %>%
    text_transform(locations = cells_body(
        columns = all_of(2),
        rows = all_of(2)
    ), fn = function(x) {
        paste0(x, "<br>", 2)
    })

tab <- tab %>%
    text_transform(locations = cells_body(
        columns = all_of(3),
        rows = all_of(3)
    ), fn = function(x) {
        paste0(x, "<br>", 3)
    })
tab

But this is only realistic for very small tables as this one here. Anyone an Idea where I messed up?


Solution

  • Thank you very much Limey I was able to solve this problem using lapply:

    library(dplyr)
    library(gt)
    
    df <- as.data.frame(matrix(NA, nrow = 3, ncol = 3))
    tab <- gt(df)
    f <- function(i) {
        tab <<- tab %>%
            text_transform(locations = cells_body(
                columns = all_of(i),
                rows = all_of(i)
            ), fn = function(x) {
                paste0(x, "<br>", i)
            })
    }
    tab
    
    lapply(1:3, f)
    tab