I have looked on SO (e.g. here) but am yet to find something that does what I need.
I am learning how to program in the new dplyr v1.0.0
and am trying to find a way to pass the results of a function that returns a two-item list, one of which is a string and the other a table, into a two-dimensional list.
Here is a toy dataset with three binary outcome variables and five predictors, two of which are factors.
set.seed(1)
library(dplyr)
df <- tibble(outcome1 = factor(rbinom(10,1, prob = 0.5), levels = 0:1, labels = c("unmet", "met")),
outcome2 = factor(rbinom(10,1, prob = 0.2), levels = 0:1, labels = c("unmet", "met")),
outcome3 = factor(rbinom(10,1, prob = 0.8), levels = 0:1, labels = c("unmet", "met")),
pred1 = rnorm(10),
pred2 = rnorm(10,5,1),
pred3 = rnorm(10,15,3),
pred4 = factor(rep(letters[1:2],5)),
pred5 = factor(rep(letters[3:4],each=5)))
Now say I want to return the proportion of unmet vs met in each of the three outcome variables for each of the two factorial predictors.
I can write a dplyr
function that will return a table of unmet vs met for a specified outcome variable for a specified predictor
catFunct_grouped <- function(d, group_var, out_var) {
d %>%
group_by(.data[[group_var]], .data[[out_var]]) %>%
summarise(count = n()) %>%
mutate(tot = sum(count),
perc = round(100*count/tot,2))
}
df %>% catFunct_grouped("pred4", "outcome1")
#output
# pred4 outcome1 count tot perc
# <fct> <fct> <int> <int> <dbl>
# 1 a unmet 2 5 40
# 2 a met 3 5 60
# 3 b unmet 2 5 40
# 4 b met 3 5 60
But say I now want to get all 2 x 3 = 6
pairwise combinations of the 2 factorial predictors and the three binary outcomes?
I tried creating a double for-loop, passing the six pairwise combinations (along with an extra element listing the outcome variable in question) into my function and then out into an empty list.
outNames <- paste0("outcome", 1:3)
predNames <- paste0("pred", 4:5)
grFact <- list()
for (r in 1:length(outNames)) {
for (c in 1:length(predNames)) {
grFact[[r]] <- list(outVariable = outNames[r], # prints the outcome name
outDF = list(df %>% catFunct_grouped(predNames[c], outNames[r])))
}
}
But when I call the new list...
grFact
...I get the following output
# [[1]]
# [[1]]$outVariable
# [1] "outcome1"
#
# [[1]]$outDF
# [[1]]$outDF[[1]]
# # A tibble: 4 x 5
# # Groups: pred5 [2]
# pred5 outcome1 count tot perc
# <fct> <fct> <int> <int> <dbl>
# 1 c unmet 3 5 60
# 2 c met 2 5 40
# 3 d unmet 1 5 20
# 4 d met 4 5 80
#
#
#
# [[2]]
# [[2]]$outVariable
# [1] "outcome2"
#
# [[2]]$outDF
# [[2]]$outDF[[1]]
# # A tibble: 3 x 5
# # Groups: pred5 [2]
# pred5 outcome2 count tot perc
# <fct> <fct> <int> <int> <dbl>
# 1 c unmet 5 5 100
# 2 d unmet 4 5 80
# 3 d met 1 5 20
#
#
#
# [[3]]
# [[3]]$outVariable
# [1] "outcome3"
#
# [[3]]$outDF
# [[3]]$outDF[[1]]
# # A tibble: 4 x 5
# # Groups: pred5 [2]
# pred5 outcome3 count tot perc
# <fct> <fct> <int> <int> <dbl>
# 1 c unmet 1 5 20
# 2 c met 4 5 80
# 3 d unmet 1 5 20
# 4 d met 4 5 80
...which is on the right track but is showing the proportion of met vs unmet for each of the three outcomes for the second predictor only.
I assume I need a matrix or array of lists to pass the tables into but am unsure of the syntax for doing this with a for-loop.
Any help much appreciated.