2
votes

I want to summarise variables by group for every variable in a dataset using dplyr. The summarised variables should be stored under a new name.

An example:

df <- data.frame(
  group = c("A", "B", "A", "B"),
  a = c(1,1,NA,2),
  b = c(1,NA,1,1),
  c = c(1,1,2,NA),
  d = c(1,2,1,1)
)

df %>% group_by(group) %>% 
  mutate(complete_a = sum(complete.cases(a))) %>% 
  mutate(complete_b = sum(complete.cases(b))) %>%
  mutate(complete_c = sum(complete.cases(c))) %>% 
  mutate(complete_d = sum(complete.cases(d))) %>% 
  group_by(group, complete_a, complete_b, complete_c, complete_d) %>% summarise()

results in my expected output:

# # A tibble: 2 x 5
# # Groups:   group, complete_a, complete_b, complete_c [?]
# group complete_a complete_b complete_c complete_d
# <fct>      <int>      <int>      <int>      <int>
# A              1          2          2          2
# B              2          1          1          2

How can I generate the same output without duplicating the mutate statements per variable?

I tried:

df %>% group_by(group) %>% summarise_all(funs(sum(complete.cases(.))))

which works but does not rename the variables.

1

1 Answers

2
votes

You are almost there. You have to use rename_all

library(dplyr)

df %>% 
  group_by(group) %>% 
  summarise_all(funs(sum(complete.cases(.)))) %>% 
  rename_all(~paste0("complete_", colnames(df)))

# A tibble: 2 x 5
#  complete_group complete_a complete_b complete_c complete_d
#  <fct>               <int>      <int>      <int>      <int>
#1 A                       1          2          2          2
#2 B                       2          1          1          2

Edit

Or as pointed all by @symbolrush, more directly without colnames:

df %>% 
  group_by(group) %>% 
  summarise_all(funs(sum(complete.cases(.)))) %>% 
  rename_all(~paste0("complete_", .))

## A tibble: 2 x 5
#  complete_group complete_a complete_b complete_c complete_d
#  <fct>               <int>      <int>      <int>      <int>
#1 A                       1          2          2          2
#2 B                       2          1          1          2