I have a list of length N, and each list element is 10 character strings sampled from some bigger group. I want to find every pair of elements that are very similar, say with >=8 strings in common. I can do this alright for N<10,000 using crossprod, but I run out of memory for larger N.
Here's an example where N=1000, resulting in 6 very similar pairs:
# make list x
set.seed(1)
N = 1000
x = lapply(1:N, function(x) sample(letters, 10))
names(x) = as.character(1:length(x))
# find pairwise intersect, store in square matrix N_intersect
N_intersect = x %>% stack() %>% table() %>% crossprod()
diag(N_intersect) = 0
N_intersect[lower.tri(N_intersect)] = 0
# find when N_intersect is over some threshold
result = which(N_intersect > 8, arr.ind = T)
result
ind ind
111 111 375
705 705 708
48 48 771
317 317 797
566 566 883
705 705 958
However since the output of crossprod is an NxN matrix, it quickly goes out of memory for large N. I know there are sparse methods for crossprod, but that only seems to reduce the memory by around ~30%.
The thing is, the number of highly similar elements is usually super small, like 1/1000 pairs. So I don't need to store the big square matrix from crossprod, but I can't think of a memory-efficient method that can do this quickly. I could just check each pair of elements in a for loop, but that takes a few hours.
