Another solution that works independently of the A, M and remaining values using table and map_dfr offered via purrr:
library("tidyverse")
df <- read.table (text = " Id san1 san2 san3
1 A A A
2 A A A
3 A M M
4 M A A
", header = TRUE)
df %>%
pivot_longer(-Id) %>%
pivot_wider(names_from = Id, values_from = value) %>%
rename(San = name) %>%
bind_cols(map_dfr(df, table)[-1, -c(1:nrow(df))])
Results
# A tibble: 3 x 7
San `1` `2` `3` `4` A M
<chr> <chr> <chr> <chr> <chr> <table> <table>
1 san1 A A A M 3 1
2 san2 A A M A 3 1
3 san3 A A M A 3 1
More interesting example
Adding pesky Z value.
df_two <- df
df_two[2,3] <- "Z"
sum_those_letters <- function(.data, nice_id_col = Id, pretty_name = "San") {
.data %>%
pivot_longer(-{{nice_id_col}}) %>%
pivot_wider(names_from = {{nice_id_col}}, values_from = value) %>%
rename(pretty_name = name) %>%
bind_cols(map_dfr(df_two, table)[-1, -c(1:nrow(.data))])
}
Results
sum_those_letters(df_two, Id)
# A tibble: 3 x 8
San `1` `2` `3` `4` A M Z
<chr> <chr> <chr> <chr> <chr> <table> <table> <table>
1 san1 A A A M 3 1 NA
2 san2 A Z M A 2 1 1
3 san3 A A M A 3 1 NA