Ophelie
Ophelie

Reputation: 713

R : count similar numbers in two vectors

  shared_numbers<- function(x, y){
  shared_numbers=0
  for(r in 1:5) {
    for(c in 1:5) {
      if (x[c]==result[r]){shared_numbers = shared_numbers+1}  
    }
  }
  return(shared_numbers)
}

#Example
shared_numbers(c(12, 17, 37, 58, 81, 89),  c(4, 19, 37, 81, 87, 19))
[1] 2

The problem is this function is very slow when I need to use it a lot. I think it because of the loops, but I don't know how to avoid them.

Question : How to optimize this function ? Thanks Richard, sum(result %in% combination) works very well.

Question 2 : How to apply this shared_number function to thousands of combination without using a for loop ?

Upvotes: 1

Views: 75

Answers (2)

Retired Data Munger
Retired Data Munger

Reputation: 1445

Just use the 'intersect' function:

> length(intersect(c(12, 17, 37, 58, 81, 89)
+         ,  c(4, 19, 37, 81, 87, 19)
+         )
+     )
[1] 2
> 

Upvotes: 1

Rich Scriven
Rich Scriven

Reputation: 99321

You can get away from the looping by using %in%

result <- c(12, 17, 37, 58, 81, 89)
combo <- c(4, 19, 37, 81, 87, 19)
sum(result %in% combo)
# [1] 2

You could replicate this, say twelve times, with

set.seed(25)
repCombo <- replicate(12, sample(90, 6), simplify = FALSE)
vapply(repCombo, function(x) sum(result %in% x), 1L)
# [1] 0 1 0 0 0 0 0 0 2 1 0 1

With regard to your comment about different data structures, this would work

lottoSum <- function(result, combo) 
{
    f <- function(x, y) sum(x %in% y)
    if (is.matrix(combo)) {
        apply(combo, 2, f, x = result)
    } else if (is.vector(combo) && is.atomic(combo)) {
        f(result, combo)
    } else {
        vapply(combo, f, x = result, 1L, USE.NAMES = FALSE)
    }
}

lottoSum(result, as.data.frame(repCombo))      ## data frame
# [1] 0 1 0 0 0 0 0 0 2 1 0 1
lottoSum(result, repCombo)                     ## list
# [1] 0 1 0 0 0 0 0 0 2 1 0 1
lottoSum(result, combo)                        ## vector
# [1] 2
lottoSum(result, matrix(unlist(repCombo), 6))  ## matrix
# [1] 0 1 0 0 0 0 0 0 2 1 0 1

Upvotes: 1

Related Questions