С помощью dplyr, tidyr и lubridate мы можем создать два обобщенных фрейма данных, один для пакетов и один для итогов, а затем объединить их, используя bind_rows
.
library(lubridate)
library(dplyr)
library(tidyr)
Теперь создайте два кадра данных. Первые группы по месяцам и партиям, вторые только по месяцам:
df_batch <- df %>%
mutate(date = as.POSIXct(date), resp=strsplit(resp, ",")) %>%
unnest(resp) %>%
group_by(month=month(date), batch) %>%
count(resp) %>%
mutate(Total=max(n), p=100*n/Total) %>%
pivot_wider(names_from=resp, values_from=c(n,p), values_fill=list(n=0, p=0)) %>%
ungroup() %>%
mutate(p_Total=100*Total/sum(Total)) %>%
select(month,batch,starts_with("n"),Total,starts_with("p"))
df_totals <- df %>%
mutate(date = as.POSIXct(date), resp=strsplit(resp, ",")) %>%
group_by(month=month(date)) %>%
mutate(Total=n()) %>%
unnest(resp) %>%
count(Total, resp) %>%
mutate(p=100*n/Total) %>%
pivot_wider(names_from=resp, values_from=c(n, p)) %>%
mutate(batch="Total", p_Total=100)
bind_rows(df_batch, df_totals)
# A tibble: 7 x 10
month batch n_ES n_RT n_AL Total p_ES p_RT p_AL p_Total
<dbl> <chr> <int> <int> <int> <int> <dbl> <dbl> <dbl> <dbl>
1 1 E 1 1 0 1 100 100 0 14.3
2 1 Q 1 1 1 1 100 100 100 14.3
3 1 R 1 1 0 1 100 100 0 14.3
4 1 T 1 1 2 2 50 50 100 28.6
5 1 W 1 0 1 1 100 0 100 14.3
6 1 Y 1 1 1 1 100 100 100 14.3
7 1 Total 6 5 5 7 85.7 71.4 71.4 100
Это не совсем в вашем формате, но результаты точно такие же, и он должен работать для нескольких месяцев.
Данные :
structure(list(Id = c("uv-1", "uv-2", "uv-3", "uv-4", "uv-5",
"uv-6", "uv-7"), date = c("2020-01-10 15:13:16", "2020-01-11 17:13:16",
"2020-01-12 18:13:16", "2020-01-13 12:13:16", "2020-01-14 13:13:16",
"2020-01-15 13:13:16", "2020-01-17 11:13:16"), price = c(1000L,
5000L, 2000L, 3000L, 1600L, 1600L, 1300L), batch = c("Q", "W",
"E", "R", "T", "T", "Y"), resp = c("ES,RT,AL", "ES,AL", "ES,RT",
"ES,RT", "RT,AL", "ES,AL", "ES,RT,AL")), class = "data.frame", row.names = c(NA,
-7L))