title: fuzzyjoin with dates in R
body: <p>I am working on a project where I am analyzing individual-level survey data within countries based on outcomes of sports matches across countries and I am not sure what the most efficient way to produce the merge that I want is.</p>
  
  <p>I am working on two separate datasets. One contains individual-level data nested within countries. The data might look something like this:</p>
  
  <pre><code>country &lt;- c(rep("Country A", 4), rep("Country B", 6))
  date &lt;- c("2000-01-01", "2000-01-02", "2000-01-03", "2000-01-04", rep("2000-01-01", 2), "2000-01-02", rep("2000-01-03", 3))
  outcome &lt;- rnorm(10)
  individual_data &lt;- cbind.data.frame(country, date, outcome)
  rm(country, date, outcome)
  </code></pre>
  
  <p>The other has country-match level data, which will look something like this:</p>
  
  <pre><code>date &lt;- rep("2000-01-02", 2)
  country &lt;- c("Country A", "Country B")
  opponent &lt;- c("Country B", "Country A")
  match_outcome &lt;- c("L", "W")
  match_data &lt;- cbind.data.frame(date, country, opponent, match_outcome)
  rm(date, country, opponent, match_outcome)
  </code></pre>
  
  <p>In this example, there's just one match, played on January 2nd, 2000, where country A lost to country B. I would like to perform a <code>fuzzy_join</code> so that as opposed to this <code>left_join</code> here, the <code>match_data</code> matches up with the <code>individual_data</code> even if the date isn't exact.</p>
  
  <pre><code># incorrect
  merged &lt;- left_join(individual_data, match_data)
  </code></pre>
  
  <p>I would like to do this with a range of 3 days, and I would like an indicator of how many days it is before and after the match within this range. The final product would look something like this:</p>
  
  <pre><code>country &lt;- c(rep("Country A", 4), rep("Country B", 6))
  date &lt;- c("2000-01-01", "2000-01-02", "2000-01-03", "2000-01-04", rep("2000-01-01", 2), "2000-01-02", rep("2000-01-03", 3))
  outcome &lt;- rnorm(10)
  opponent &lt;- c(rep("Country B", 4), rep("Country A", 6))
  match_outcome &lt;- c(rep("L", 4), rep("W", 6))
  match_date &lt;- rep("2000-01-02", 10)
  difference &lt;- c(-1, 0, 1, 2, -1, -1, 0, rep(1, 3))
  desired_output &lt;- cbind.data.frame(country, date, outcome, opponent, match_outcome, match_date, difference)
  rm(country, date, outcome, opponent, match_outcome, match_date, difference)
  </code></pre>
  
  <p>Can anyone help me out? I've been really struggling with how to get this done. Here is what I've tried so far:</p>
  
  <pre><code>match_data$match_date_minus3 &lt;- ymd(match_data$date) - days(3)
  match_data$match_date_plus3 &lt;- ymd(match_data$date) + days(3)
  
  test_output &lt;- fuzzy_left_join(individual_data, match_data,
                                  by = c("country" = "country",
                                         "match_date_minus3" = "date",
                                         "match_date_plus3" = "date"),
                                  match_fun = list("==", "&gt;", "&lt;"))
  </code></pre>
  
  <p>but I get the following error: <code>Error in which(m) : argument to 'which' is not logical</code></p>
  
  <p>For reference if anyone is aware, I'm trying to replicate the results of <a href="https://www.diw.de/documents/dokumentenarchiv/17/diw_01.c.614233.de/durante_bams_apr2019.pdf" rel="nofollow noreferrer">Depeteris-Chauvin et al. 2018</a>.</p>