title: Best Match of each element in of a string with many strings
body: <p>Input Data:</p>
  
  <pre><code>a &lt;- c("coca cola","hot coffee","Running Shoes","Table cloth",
         ”mobile phones under 5000”,”Amazon kindle”)
  b &lt;- c("running shoes","plastic cup","pizza","Let’s go to hill","motor van",
         "coffee table","drinking coffee on a rainy day",”Best mobile phones under 10000”,
         ”kindle e-books”,”Coffee Cup”)
  </code></pre>
  
  <p>Match each word of each sentence of a vector (here vector a) to all strings in a separate vector(here vector b) word by word and get the best match. </p>
  
  <p><a href="https://i.stack.imgur.com/Qbnya.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Qbnya.png" alt="The expected output"></a></p>
  
  <p>Logic:
  All sentence of vector “a” has to be matched with all sentences of vector “b” word by word and a percentage has to be calculated. 
  There can be only one best match per sentence of vector “a”.</p>
  
  <p>Example 1: “Running Shoes” in vector “a” matched perfectly with “Running Shoes” in vector “b” and the <code>percentage_match</code> is 100% (since both the words matched) </p>
  
  <p>Example 2: the best match of  “hot coffee”  may be  “drinking coffee on a rainy day” or “coffee table” or “Coffee cup” and the percentage_match is 50% (since only “coffee”, matched out of “hot coffee” in all the cases). In such scenario, where there is more than one contender with same max <code>percentage_match</code>, we will choose the best match with the lowest string length i.e “coffee table” and “coffee cup” gets priority over “drinking coffee on a rainy day”. Even after doing this, there is a tie, we are free to choose any thing (i.e either of “Coffee Table” or “Coffee cup”, can be the best match for “hot coffee”. </p>
  
  <p>Code Tried:</p>
  
  <pre><code>as &lt;- strsplit(a, " ")
  bs &lt;- strsplit(b, " ")
  
  matchFun &lt;- function(x, y) length(intersect(x, y)) / length(x) * 100
  mx &lt;- outer(as, bs, Vectorize(matchFun))
  
  m &lt;- apply(mx, 1, which.max)  # the maximum column of each row
  
  z &lt;- unlist(apply(mx, 1, function(x) x[which.max(x)]))  # maximum percentage
  z[z == 0] &lt;- NA  # this gives you the NA if you want it
  
  data.frame(a, Matching_String=b[m], match_perc=z)
  </code></pre>
  
  <p>Problem faced: Since my actual data is very big (more than 2 million records are to be matched with 1 Mn record), this code takes forever.</p>