简体   繁体   中英

using (m)apply to substitute more than 1 variable iteratively into a function?

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.

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")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM