Skip to content

Instantly share code, notes, and snippets.

@mmahmoudian
Created September 9, 2022 16:41
Show Gist options
  • Save mmahmoudian/ac5cfa9eee14624f25f894e80a96a748 to your computer and use it in GitHub Desktop.
Save mmahmoudian/ac5cfa9eee14624f25f894e80a96a748 to your computer and use it in GitHub Desktop.
venn_zones <- function(lst, output = "data.frame", verbose = TRUE){
## Description:
## A function to get the items in each zone of a venn diagram when
## provided with the exact list that was given to a venn::venn().
##
## Arguments:
## lst: The exact list that was given to a venn::venn()
## output: The format that the output should be returned. Valid options are
## "data.frame" and "list".
## verbose: If the function should show which zone it is working on
##
## Example:
## set.seed(12345)
## a <- list(list1 = sample(x = letters, size = 20),
## list2 = sample(x = letters, size = 20),
## list3 = sample(x = letters, size = 20))
## res <- venn_zones(a)
## comment(res)
# create all the combinations
combinations <- lapply(seq_along(lst), function(x){ combn(x = seq_along(lst), m = x, simplify = F) })
# create empty objects to be filled in the following for loop
collective_list <- list()
collective_names <- c()
# iterate through the major combinations
for(i in seq_along(combinations)){
tmp1 <- combinations[[i]]
# iterate through the minor combinations
for(j in seq_along(tmp1)){
tmp2 <- tmp1[[j]]
if(is.null(names(lst))){
tmp_name <- tmp2
}else{
tmp_name <- names(lst)[tmp2]
}
if(verbose){
print(tmp_name)
}
# create the name of the zone and append it to the collective variable
collective_names <- c(collective_names, paste0("only.in.", paste(tmp_name, collapse = "&")))
# get the intersect of the selected sets (this might include some that are also belonging to other sets)
if(length(tmp_name) == 1){
tmp_pool <- unlist(lst[tmp_name])
}else{
tmp_pool <- intersect2(lst[tmp_name])
}
# subtract the items that are not specific to the sets we are intersecting
tmp_res <- setdiff(tmp_pool, unique(unlist( lst[names(lst)[-tmp2]] )))
# append to collective variable
collective_list <- lappend(collective_list, tmp_res)
}
}
# apply the names to the list
names(collective_list) <- collective_names
#-------[ prepare output ]-------#
{
if(output == "data.frame"){
# convert the list to dataframe with NA for filling
result <- list2df(l = collective_list, byrow = F, stringsAsFactors = F, filler = NA)
}else if(output == "list"){
result <- collective_list
}
# clarify the names through the comments
comment(result) <- paste("This file contains the items in each zone of the venn diagram (one column per zone).",
"As for the column names we have used the numerical value in front of the following",
"to make the column names easeir to read:",
paste("[", seq_along(names(lst)), "]", names(lst), collapse = "\n"),
sep = "\n")
}
return(result)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment