user9588528
user9588528

Reputation: 411

combination values in R for venn diagram

I want to plot circles within circles. I have been successful creating a triple with the following breakdown in my code:

venn.plot <- draw.triple.venn(
area1 = 1171,
area2 = 979,
area3 = 579,
n12 = 979,
n13 = 579,
n23 = 579,
n123 = 579,

The smallest circle is 579, the next circle adds 400 to be a total of 979 and the next adds 192 to be a total of 1171.

I want to extend this to 5 levels, with the next adding 52 to be 1223 and the last adding 11 to be 1234.

I can not work out the combination values to successfully produce a diagram. The error I get is

ERROR [2018-05-04 16:05:48] Impossible: a5 <- area5 - a6 - a7 - a15 - a16 - a17 - a18 - a25 - a26 - a27 - a28 - a31 - a20 - a29 - a21 - a10 produces negative area Error in draw.quintuple.venn(area1 = 1234, area2 = 1223, area3 = 1171,  :   Impossible: a5 <- area5 - a6 - a7 - a15 - a16 - a17 - a18 - a25 - a26 - a27 - a28 - a31 - a20 - a29 - a21 - a10 produces negative area

Obviously I am adding up wrong.

What are the n values I should be using for these? n12 = n13 = n14 = n15 = n23 = n24 = n25 = n34 = n35 = n45 = n123 = n124 = n125 = n134 = n135 = n145 = n234 = n235 = n245 = n345 = n1234 = n1235 = n1245 = n1345 = n2345 = n12345 =

Upvotes: 1

Views: 348

Answers (1)

missuse
missuse

Reputation: 19716

If I understand you would like each set to be a subset of another. Here is the call:

library(VennDiagram)
venn.plot <- draw.quintuple.venn(
  area1 = 579L,
  area2 = 979L,
  area3 = 1171L,
  area4 = 1223L,
  area5 = 1234L,
  n12 = 579L,
  n13 = 579L,
  n14 = 579L,
  n15 = 579L,
  n23 = 979L,
  n24 = 979L,
  n25 = 979L,
  n34 = 1171L,
  n35 = 1171L,
  n45 = 1223L,
  n123 = 579L,
  n124 = 579L,
  n125 = 579L,
  n134 = 579L,
  n135 = 579L,
  n145 = 579L,
  n234 = 979L,
  n235 = 979L,
  n245 = 979L,
  n345 = 1171L,
  n1234 = 579L,
  n1235 = 579L,
  n1245 = 579L,
  n1345 = 579L,
  n2345 = 979L,
  n12345 = 579L)

enter image description here

each area intersection is equal to the minimum of the areas participating in it.

Now this is too cumbersome especially if you need to perform it often, here is a programmatic way:

define your set:

val = c(579, 979, 1171, 1223, 1234)

name it

names(val) ;- LETTERS[1:length(val)]

maybe there is a more elegant way, but from the top of my head:

z <- lapply(1:length(val),function(x){
  comb <- combn(names(val), m = x) #all combination of 1:5 elements of names
  value <- apply(comb, 2, function(i){ #for each combination return minumum from val vector
    return(min(val[names(val) %in% i]))
  })
  set <- apply(comb, 2, paste0, collapse = "&", sep = "") #paste the names with "&" in beetwean
  names(value) = set
  return(value)
})

run each line of code separately (use 3 instead of x for instance) to understand what it does.

z <- unlist(z)

library(eulerr) # a nice library
plot(euler(z, input = "union"), quantities = T)

enter image description here

lets make it into a function:

create_eulerr_data <- function(val){
  z <- lapply(1:length(val),function(x){
  comb <- combn(names(val), m = x)
  value <- apply(comb, 2, function(i){
    return(min(val[names(val) %in% i]))
  })
  set <- apply(comb, 2, paste0, collapse = "&", sep = "")
  names(value) = set
  return(value)
  })
  z <- unlist(z)
  }

now the good thing about this is that it will work for any number of sets:

val <- c(26, 53, 78)
names(val) <- LETTERS[1:length(val)]
plot(euler(create_eulerr_data(val),
           input = "union"),
     quantities = T)

enter image description here

or

val <- c(26, 53, 78, 112, 134, 158)
names(val) <- LETTERS[1:length(val)]
plot(euler(create_eulerr_data(val),
           input = "union"),
     quantities = T)

enter image description here

it will work even if you provide the values unarranged:

val <- c(26, 78, 53)
names(val) <- LETTERS[1:length(val)]
plot(euler(create_eulerr_data(val),
           input = "union"),
     quantities = T)

enter image description here

Upvotes: 2

Related Questions