0
votes

This question is based on the following post with additional requirements (Iterate through columns in dplyr?).

The original code is as follows:

df <- data.frame(col1 = rep(1, 15),
      col2 = rep(2, 15),
      col3 = rep(3, 15),
      group = c(rep("A", 5), rep("B", 5), rep("C", 5)))

for(col in c("col1", "col2", "col3")){
      filt.df <- df %>%
      filter(group == "A") %>% 
      select_(.dots = c('group', col))
      # do other things, like ggplotting
      print(filt.df)
}

My objective is to output a frequency table for each unique COL by GROUP combination. The current example specifies a dplyr filter based on a GROUP value A, B, or C. In my case, I want to iterate (loop) through a list of values in GROUP (list <- c("A", "B", "C") and generate a frequency table for each combination.

The frequency table is based on counts. For Col1 the result would look something like the table below. The example data set is simplified. My real dataset is more complex with multiple 'values' per 'group'. I need to iterate through Col1-Col3 by group.

group value n prop
A       1       5      .1
B       2       5       .1
C       3       5      .1

A better example of the frequency table is here: How to use dplyr to generate a frequency table

I struggled with this for a couple days, and I could have done better with my example. Thanks for the posts. Here is what I ended up doing to solve this. The result is a series of frequency tables for each column and each unique value found in group. I had 3 columns (col1, col2, col3) and 3 unique values in group (A,B,C), 3x3. The result is 9 frequency tables and a frequency table for each group value that is non-sensical. I am sure there is a better way to do this. The output generates some labeling, which is useful.

# Build unique group list
group <- unique(df$group)

# Generate frequency tables via a loop
iterate_by_group <- function(x)
 for (i in 1:length(group)){ 
  filt.df <- df[df$group==group[i],]
  print(lapply(filt.df, freq))
}

# Run 
iterate_by_group(df)
2

2 Answers

0
votes

Is this what you want?

df %>%
  group_by(group) %>%
  summarise_all(funs(freq = sum))
0
votes

We could gather into long format and then get the frequency (n()) by group

library(tidyverse)
gather(df, value, val, col1:col3) %>%
        group_by(group, value = parse_number(value)) %>% 
        summarise(n = n(), prop = n/nrow(.))
# A tibble: 9 x 4
# Groups:   group [?]
#  group value     n  prop
#  <fct> <dbl> <int> <dbl>
#1 A         1     5 0.111
#2 A         2     5 0.111
#3 A         3     5 0.111
#4 B         1     5 0.111
#5 B         2     5 0.111
#6 B         3     5 0.111
#7 C         1     5 0.111
#8 C         2     5 0.111
#9 C         3     5 0.111