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) }