1

I'm trying to dynamically create an extra column. The first piece of code works as i want it to:

library(dplyr)
library(tidyr)

set.seed(1)

df <- data.frame(animals = sample(c('dog', 'cat', 'rat'), 100, replace = T))

my_fun <- function(data, column_name){

  data %>% group_by(animals) %>%
         summarise(!!column_name := n())

}

my_fun(df, 'frequency')

Here i also use the complete function and it doesn't work:

library(dplyr)

set.seed(1)

df <- data.frame(animals = sample(c('dog', 'cat', 'rat'), 100, replace = T))

my_fun <- function(data, column_name){

  data %>% group_by(animals) %>%
         summarise(!!column_name := n())%>%
         ungroup() %>%
         complete(animals = c('dog', 'cat', 'rat', 'bat'),
                  fill = list(!!column_name := 0))

}

my_fun(df, 'frequency')

The list function doesn't seem to like !!column_name :=

Is there something i can do to make this work? Basically i want the second piece of code to output:

animals frequency
bat      0
cat      38
dog      27
rat      35
Steve
  • 625
  • 2
  • 5
  • 17
  • [This](https://stackoverflow.com/questions/8161836/how-do-i-replace-na-values-with-zeros-in-an-r-dataframe) provides other approaches – prosoitos Oct 17 '19 at 11:03
  • hmm yes changing NA to 0 may be the best solution. I've been using the way i show so much that it didn't cross my mind that i don't actually have to have fill/list in the code. If someone does know a solution using the list function in my code i'd be interested in hearing it. – Steve Oct 17 '19 at 11:17
  • Maybe one of the rlang functions could allow you to use `:=` inside `list()`??? – prosoitos Oct 17 '19 at 11:22

1 Answers1

1

You could keep the fill argument of complete() as the default (which will give you the missing values as NA) and subsequently replace them with 0:

my_fun <- function(data, column_name){
  data %>%
    group_by(animals) %>%
    summarise(!!column_name := n())%>%
    ungroup() %>%
    complete(animals = c('dog', 'cat', 'rat', 'bat')) %>%
    mutate_all(~replace(., is.na(.), 0))  
}
prosoitos
  • 6,679
  • 5
  • 27
  • 41
  • I assume the dot used in the replace function's first argument represents the data which is the column mutate_all is looking at. How do you know this dot could be used to represent the data? Is the dot regex? as dots represent any character in regex? If so is it kind of saying select all elements in the column which mutate_all is currently looking at? Also why is the ~ before the replace function there? What does it do? – Steve Oct 17 '19 at 11:52
  • The `.` is not a regexp dot. It is a placeholder used by the tidyverse packages. And the `~` is also a tidyverse notation. Have a look at the documentation of the purrr package for explanations on these – prosoitos Oct 17 '19 at 23:57
  • The `~` is a shortcut notation for anonymous functions – prosoitos Oct 17 '19 at 23:59