Search code examples
rgt

Use weighted.mean in summary_rows GT package


I've been searching around for a solution to using weighted.mean with summary_rows in GT package.

summary_rows function only accepts functions in form foo(x), therefore functions with more variables such as weighted.mean(x,w) is not accepted.

When using summary_rows with groups, such as:

summary_rows(groups = T, columns = c, fns = list("average" = ~mean(.)),...)

It takes vector of values for each group and then runs them through the mean() function, resp. the list of chosen functions.

My solution to this is quite cumbersome. I wrote my own custom function, that takes the vector of values provided by summary_rows and compares it to expected vectors using if statements. This only works for single columns at a time so it is quite a lot of code, both in the custom functions and in the code for the GT table.

weighted_mean_age <- function (x) {
  if (all(x == some.data$age.column[some.data$group.column == "group name"])) {
    weighted.mean(x, some.data$no.occurences[some.data$group.column == "group name"])
  } else if (another vector) {
    And so on for every group.
  } 
}

Did anyone deal with the same problem, but came up with less cumbersome solution? Did I miss something in the GT package?

Thank you for your time and ideas.


Solution

  • First I need to clarify the assumption that I used for this answer:

    What you want is to pass something like weighted.mean(.,w) to this summary_rows() function. However this isn't possible due to the problems with the gt library that you outlined in your question. If that is the case then I do believe I have a solution:

    I've done some similar 'hacks' when I was creating some very specific Python scripts. It essentially revolved around mapping the functions that I wanted to use using some specific container. Thus I searched the R language sources if something like this is also possible in R and apparently it is using factory functions and storing them in some container. Here is a step by step guide:

    You first need to create a factory function for your weighted.mean as such:

    my_mean <- function(w) { function(x) { weighted.mean(x,w) } }
    

    then you need to populate some kind of a container with your new functions (I am using a list):

    func_list <- list()
    func_list[[some_weight]] <- my_mean(some_weight)
    func_list[[different_w]] <- my_mean(different_w)
    #etc...
    

    Once you've done that you should be able to pass this as a function to summary_rows i.e.:

     summary_rows(
               groups = T,
               columns   = c,
               fns       = list("w_mean" = ~func_list[w](.)),
               ...)
    

    Bare in mind that you have to put the w values in yourself using some form of a mapping function or a loop.

    Hope it is what you are looking for and I hope it helps!