Search code examples
rfor-loopgroup-bydplyrsummarize

Summarizing using dplyr with a for loop


I would like to summarise each of my independant variables (columns) with my target variable using dplyr over a for loop. This is my main dataframe:

  contract_ID    Asurion         Variable_1     Variable_2  Variable_3
         1          Y                a               c          f
         2          Y                a               d          g
         3          N                b               c          g
         4          N                a               d          f
         5          Y                b               c          f
         6          Y                a               d          f

After the group by I get

a1 <- a %>% 
  group_by(Asurion,BhvrBnk_Donates_to_Env_Causes) %>%       
  summarise(counT=n_distinct(CONTRACT_ID)) %>%                                        
  mutate(perc=paste0(round(counT/sum(counT)*100,2),"%"))

 Asurion Variable_1 CounT   perc
    Y         a        3     75%
    Y         b        1     25%
    N         a        1     50%
    N         b        1     50%

I would like to have this summairsation for each of my variable present in my dataframe and I would like to do this using a for loop. How do i get to my desired result

This is what I have tried using but it doesnt seem to work. it is for a school project and I need to use a for loop for this. Please help me out here

categorical <- colnames(a)###where categroical is the names of all columns in a  
###I would like to have a for loop for every column in a and summarise in the following way. I would like to store each of the summarisations in a separate dataframe 

for (i in categorical) {
  a[[i]] <- a %>% 
     group_by(Asurion,get(i)) %>% 
    summarise(counT=n_distinct(CONTRACT_ID)) %>% 
    mutate(perc=paste0(round(counT/sum(counT)*100,2),"%"))
  }

Solution

  • You may not really need for loop to get what you wanted.

    df<-data.frame(contract_ID = 1:6, 
                   Asurion = c("Y", "Y", "N", "N", "Y", "Y"), 
                   Variable_1 = c("a", "a", "b", "a", "b","a"), 
                   Variable_2 = c("c", "d", "c", "d", "c", "d"), 
                   Variable_3 = c("f", "g", "g", "f", "f", "f"))
    
    pct <- function(x) {
      df %>% 
      group_by(Asurion, {{x}}) %>% 
      summarise(counT=n_distinct(contract_ID)) %>% 
      mutate(perc = paste0(round(counT/sum(counT)*100,2),"%"))
    }
    
    pct(Variable_1)
    pct(Variable_2)
    pct(Variable_3)
    

    If you do have many variables, you could use something like for loop or apply to iterate the last bit. Here is one option:

    categorical<- df[3:5]
    a <- list()
    j = 1
    for (i in categorical) {
      a[[j]] <- df %>% 
        group_by(Asurion, {{i}}) %>% 
        summarise(counT=n_distinct(contract_ID)) %>% 
        mutate(perc = paste0(round(counT/sum(counT)*100,2),"%"))
      j = j + 1
    }
    a
    
    [[1]]
    # A tibble: 4 x 4
    # Groups:   Asurion [2]
      Asurion `<fct>` counT perc 
      <fct>   <fct>   <int> <chr>
    1 N       a           1 50%  
    2 N       b           1 50%  
    3 Y       a           3 75%  
    4 Y       b           1 25%  
    
    [[2]]
    # A tibble: 4 x 4
    # Groups:   Asurion [2]
      Asurion `<fct>` counT perc 
      <fct>   <fct>   <int> <chr>
    1 N       c           1 50%  
    2 N       d           1 50%  
    3 Y       c           2 50%  
    4 Y       d           2 50%  
    
    [[3]]
    # A tibble: 4 x 4
    # Groups:   Asurion [2]
      Asurion `<fct>` counT perc 
      <fct>   <fct>   <int> <chr>
    1 N       f           1 50%  
    2 N       g           1 50%  
    3 Y       f           3 75%  
    4 Y       g           1 25%  
    

    EDIT Add variable names as new variable values in response to your question to identify group_by variables.

    categorical<- df[3:5]
    vnames <- colnames(categorical)
    a <- list()
    j = 1
    for (i in categorical) {
      a[[j]] <- df %>% 
        group_by(Asurion, {{i}}) %>% 
        summarise(counT=n_distinct(contract_ID)) %>% 
        mutate(perc = paste0(round(counT/sum(counT)*100,2),"%"))
        a[[j]]$vnames = vnames[j]
      j = j + 1
    }
    a