Reputation: 23
I have a dataframe with 10 columns for different demographic variables, and 38 columns for responses to 38 different questions from survey participants. to make a smaller dataframe that replicates the organization:
ID <- c("a", "b", "c", "d", "e")
Gender <- c("Male", "Female", "Male", "Female", "Male")
Pain_Level <- c("High", "Moderate", "Low", "High", "Moderate")
Q1 <- c("Agree", "Strongly Agree", "Disagree", "Neutral", "Agree")
Q2 <- c("Disagree", "Strongly Agree", "Disagree", "Neutral", "Agree")
Q3 <- c("Agree", "Strongly Disagree", "Disagree", "Neutral", "Agree")
df<- data.frame(ID, Gender, Pain_Level, Q1, Q2, Q3)
I want to apply function xtabs to each of the question columns (Q1-38) of the dataframe to get contingency tables for each question, per demographic variable. I was able to create a function that can do this for all 38 questions, but only for one demographic at a time using:
varlist <- names(select(df, starts_with("Q")))
xtabs <- lapply(varlist, function(x) {
xtabs(substitute(~Pain_Level + i, list(i = as.name(x))), data = df)
}
)
Basically, I'd like to be able to then iteratively substitute Pain Level in the above equation, with Gender, and then all my other demographic variables, so I end up with a list of contingency tables: 38 tables per each demographic, for each question.
I have tried fiddling around with mapply, things like:
demolist <- names(select(df,"Pain_Level", "Gender"))
myfun <- function(x,y) {
xtabs(substitute(~j + i, list(i = as.name(y), j=as.name(x))), data=df)
}
attempt1 <- mapply(myfun, demolist, MoreArgs = list(varlist))
attempt2 <- mapply(myfun, demolist, varlist)
But what ends up happening is... it won't go through every combination of demographic / question. So I feel like I need to use lapply somehow but haven't had much success there either.
I feel like I am missing something - like approaching this from a fundamentally wrong way... but I am pretty new to programming so am having difficulty troubleshooting / thinking of alternatives. Any help is greatly appreciated.
Upvotes: 2
Views: 59
Reputation: 887098
The Map/mapply
loop over the corresponding elements (for that purpose, it needs the arguments to be of same length or else it can do recycling when there is a single element) and doesn't do all the combinations. If we need all combinations, either expand.grid
or outer
is needed
c(outer(demolist, varlist, Vectorize(myfun)))
Or using tidyverse
library(dplyr)
library(tidyr)
library(purrr)
crossing(demolist, varlist) %>%
pmap(~ myfun(..1, ..2))
#[[1]]
# Q1
#Gender Agree Disagree Neutral Strongly Agree
# Female 0 0 1 1
# Male 2 1 0 0
#[[2]]
# Q2
#Gender Agree Disagree Neutral Strongly Agree
# Female 0 0 1 1
# Male 1 2 0 0
#[[3]]
# Q3
#Gender Agree Disagree Neutral Strongly Disagree
# Female 0 0 1 1
# Male 2 1 0 0
#[[4]]
# Q1
#Pain_Level Agree Disagree Neutral Strongly Agree
# High 1 0 1 0
# Low 0 1 0 0
# Moderate 1 0 0 1
#[[5]]
# Q2
#Pain_Level Agree Disagree Neutral Strongly Agree
# High 0 1 1 0
# Low 0 1 0 0
# Moderate 1 0 0 1
#[[6]]
# Q3
#Pain_Level Agree Disagree Neutral Strongly Disagree
# High 1 0 1 0
# Low 0 1 0 0
# Moderate 1 0 0 1
where
demolist <- c("Pain_Level", "Gender")
Upvotes: 0