Here is one option with combn. We split the 'V2' by 'V1' column, then get the combnatios of pairwise elements of list to return the length of intersecting elements, name the list elements with the pairwise concatenation of names of 'lst1', stack it to a two column data.frame, separate the concatenated column into two and rename if needed
lst1 <- split(df1$V2, df1$V1)
outlst <- combn(lst1, 2, FUN = function(x)
length(Reduce(intersect, x)), simplify = FALSE)
names(outlst) <- combn(names(lst1), 2, FUN = paste, collapse = "_")
library(dplyr)
library(tidyr)
subset(stack(outlst), values >0)[2:1] %>%
separate(ind, into = c('W1', 'W2')) %>%
rename(W3 = values)
# W1 W2 W3
#1 a1 a2 2
#2 a1 a3 1
#3 a1 a4 1
#4 a2 a3 1
#5 a2 a4 1
Or using tidyverse
library(dplyr)
library(tidyr)
df1 %>%
group_by(V2) %>%
summarise(V1 = if(n() > 1) combn(V1, 2, FUN = paste, collapse='_')
else NA_character_) %>%
ungroup %>%
filter(!is.na(V1)) %>%
separate(V1, into = c('W1', 'W2')) %>%
count(W1, W2)
# A tibble: 5 x 3
# W1 W2 n
# <chr> <chr> <int>
#1 a1 a2 2
#2 a1 a3 1
#3 a1 a4 1
#4 a2 a3 1
#5 a4 a2 1
data
df1 <- structure(list(V1 = c("a1", "a1", "a2", "a2", "a3", "a4", "a2"
), V2 = c("a4", "a5", "a4", "a6", "a4", "a5", "a5")), class = "data.frame",
row.names = c(NA,
-7L))