Base R Solution:
df2 <- data.frame(
reshape(df,
direction = "long",
varying = names(df)[!(names(df) %in% c("contract_ID", "Asurion"))],
v.names = "Val",
timevar = "Variable",
times = names(df)[!(names(df) %in% c("contract_ID", "Asurion"))]
),
row.names = NULL,
stringsAsFactors = F
)
# Count the unique contract ids within the specified group:
df2$CounT <- as.numeric(ave(df2$contract_ID,
paste(df2$Asurion, df2$Variable, df2$Val, sep = "_"),
FUN = function(x){length(unique(x))}))
# Create the percentage of total counts:
df2$perc <- paste0(round((df2$CounT/as.numeric(ave(df2$Variable,
paste(df2$Variable, df2$Val, sep = "_"),
FUN = length))) * 100,2),"%")
# Allocate some memory for list of dataframes:
df_list <- vector("list", length(unique(df2$Variable)))
# Store the summary dataframes in the list:
df_list <- lapply(split(df2, df2$Variable),
function(x){x <- unique(x[,c(!(names(x) %in% c("id", "contract_ID")))])})
# Push the dataframes from the list into the global environment:
list2env(df_list, .GlobalEnv)
Tidyverse Solution:
require(tidyverse)
# Allocate some memory for list of dataframes:
df_list <- vector("list", length(unique(names(df)[grepl("Variable_", names(df))])))
# Tidyverse summary:
df_list <-
df %>%
gather(Variable, Value, -contract_ID, -Asurion) %>%
group_by(Asurion, Variable, Value) %>%
mutate(CounT = length(unique(contract_ID))) %>%
ungroup() %>%
group_by(Variable, Value) %>%
mutate(perc = paste0(round((CounT/n()) * 100, 2), "%")) %>%
ungroup() %>%
select(-contract_ID) %>%
distinct() %>%
split(., .$Variable)
# Push the dataframes from the list into the global environment:
list2env(df_list, .GlobalEnv)
Данные:
structure(list(contract_ID = 1:6, Asurion = c("Y", "Y", "N",
"N", "Y", "Y"), Variable_1 = c("a", "a", "b", "a", "b", "a"),
Variable_2 = c("c", "d", "c", "d", "c", "d"), Variable_3 = c("f",
"g", "g", "f", "f", "f")), class = "data.frame", row.names = c(NA,
-6L))