How can I pivot wider and transform my data frame?
Solution 1:
Do a group by and return the count, and the sum
of 'Number_Students' and then use pivot_wider
with names_from
specified as the 'Grade' and the values_from
as a vector of columns
library(dplyr)
library(tidyr)
df1 %>%
group_by(School, City, Grade, Type_school) %>%
summarise(N = n(), Students = sum(Number_Students), .groups = 'drop') %>%
pivot_wider(names_from = Grade, values_from = c(N, Students), values_fill = 0)
-output
# A tibble: 4 × 9
School City Type_school N_7th N_6th N_8th Students_7th Students_6th Students_8th
<dbl> <chr> <chr> <int> <int> <int> <dbl> <dbl> <dbl>
1 1 A public 2 0 0 43 0 0
2 2 B private 1 0 0 25 0 0
3 3 C public 0 1 1 0 21 28
4 4 B private 0 0 1 0 0 34
Solution 2:
Here is an alternative approach: Not comparable with the perfect approach of akrun, but it contains some interesting feature how we could get the same result:
library(tidyr)
library(dplyr)
df1 <- df %>%
pivot_wider(id_cols = c(School, City, Grade, Type_school),
names_from = "Grade",
values_from = "Number_Students",
values_fn = list(Number_Students = length),
values_fill = 0,
names_glue = "N_{Grade}")
df %>%
pivot_wider(id_cols = c(School, City, Grade, Number_Students),
names_from = Grade,
values_from = Number_Students,
values_fn = list(Number_Students = sum),
names_glue = "Students_{Grade}"
) %>%
right_join(df1, by=c("School", "City"))
School City Students_7th Students_6th Students_8th Type_school N_7th N_6th N_8th
<dbl> <chr> <dbl> <dbl> <dbl> <chr> <int> <int> <int>
1 1 A 43 NA NA public 2 0 0
2 2 B 25 NA NA private 1 0 0
3 3 C NA 21 28 public 0 1 1
4 4 B NA NA 34 private 0 0 1