0

I am trying to retain factor levels after using summarise in a loop. I replicate my problem using a mock dataset.

df = data.frame(a=rep(1:3,4), b=rep(1:2,6),c=rep(1:2,6),d=rep(1:2,6))
df$b = factor(df$b, levels=1:3)
#the group are for the loop. Since it's just an example have only 1 value
outer_group <- c("a") 
inner_group <- c("b")

My desired output is achieved using this code hereunder. However, using this approach i need to manually change the column of complete() in case I have multiple values in the loop

for (o in outer_group){
    for(i in inner_group){
        df %>%
            group_by_at(i) %>%
            summarise(count_a=length(!!o)) %>%
            complete(b) -> a
    }

}

For such reason, I tried to change it to complete(!!i) such as

for (o in outer_group){
    for(i in inner_group){
        df %>%
            group_by_at(i) %>%
            summarise(count_a=length(!!o)) %>%
            complete(!!i) -> a
    }

}

Unfortunately, this does not work

Error: `by` can't contain join column `"b"` which is missing from RHS

Any help is appreciated

Desired output:

# A tibble: 3 x 2                                  
  b     count_a
  <fct>   <int>
1 1           1
2 2           1
3 3          NA
  • Not sure if this is what you want, but you get your desired output using: `df %>% group_by(b) %>% summarize(n()) %>% complete(b)` If this is what you want I think this is a duplicate of https://stackoverflow.com/questions/22523131/dplyr-summarise-equivalent-of-drop-false-to-keep-groups-with-zero-length-in – yoland Sep 12 '18 at 11:45
  • The post linked does not use a loop and for that reason, it's not what i am looking for. Without a loop that needed to be adopted that approach works – Alberto Stefanelli Sep 12 '18 at 11:57

1 Answers1

1

You could use wrapr::let instead of the dplyr quoting mechanism:

library(wrapr)
for (o in outer_group){
   for(i in inner_group){
     let(c(I=i),
        df %>%
          group_by_at(i) %>%
          summarise(count_a=length(!!o)) %>%
          complete(I) -> a)
    }
}
## A tibble: 3 x 2
#  b     count_a
#  <fct>   <int>
#1 1           1
#2 2           1
#3 3          NA
Nicolas2
  • 2,170
  • 1
  • 6
  • 15