title: Filtering observations using multivariate column conditions
body: <p>I'm not very experienced R user, so seek advice how to optimize what I've build and in which direction to move on.</p>
  
  <p>I have one <strong>reference</strong> data frame, it contains four columns with integer values and one ID.</p>
  
  <pre><code>df &lt;- matrix(ncol=5,nrow = 10)
  colnames(df) &lt;- c("A","B","C","D","ID")
  # df
  for (i in 1:10){
          df[i,1:4] &lt;- sample(1:5,4, replace = TRUE)
  }
  df &lt;- data.frame(df)
  df$ID &lt;- make.unique(rep(LETTERS,length.out=10),sep='')
  df
   A B C D ID
  1  2 4 3 5  A
  2  5 1 3 5  B
  3  3 3 5 3  C
  4  4 3 1 5  D
  5  2 1 2 5  E
  6  5 4 4 5  F
  7  4 4 3 3  G
  8  2 1 5 5  H
  9  4 4 1 3  I
  10 4 2 2 2  J
  </code></pre>
  
  <p>Second data frame has manual input, it's user input, I want to turn it into shiny app later on, that's why also I'm asking for optimization, because my code doesn't seem very neat to me.</p>
  
  <pre><code>df.man &lt;- data.frame(matrix(ncol=5,nrow=1))
  colnames(df.man) &lt;- c("A","B","C","D","ID")
  df.man$ID &lt;- c("man")
  df.man$A &lt;- 4
  df.man$B &lt;- 4
  df.man$C &lt;- 3
  df.man$D &lt;- 4
  df.man
   A B C D  ID
   4 4 3 4 man
  </code></pre>
  
  <p>I want to filter rows from reference sequentially, following the rules:</p>
  
  <p>If there is exact match in a whole row between <strong>reference</strong> table  and <strong>manual</strong> than extract this(those)  from reference and show me that row, if not then reduce number of matching columns from right to left until there is a match but not between less then two variables(columns A,B).</p>
  
  <p>So with my limited knowledge I've wrote this:</p>
  
  <pre><code># subtraction manual from reference 
  df &lt;- df %&gt;% dplyr::mutate(Adiff=A-df.man$A)%&gt;%
          dplyr::mutate(Bdiff=B-df.man$B)%&gt;% 
          dplyr::mutate(Cdiff=C-df.man$C) %&gt;% 
          dplyr::mutate(Ddiff=D-df.man$D)
  
  # check manually how much in a row has zero difference and filter those
  ifelse(nrow(df%&gt;%filter(Adiff==0 &amp; Bdiff==0 &amp; Cdiff==0 &amp; Ddiff==0)) != 0,
         df0&lt;-df%&gt;%filter(Adiff==0 &amp; Bdiff==0 &amp; Cdiff==0 &amp; Ddiff==0),
         ifelse(nrow(df%&gt;%filter(Adiff==0 &amp; Bdiff==0 &amp; Cdiff==0)) != 0,
                df0&lt;-df%&gt;%filter(Adiff==0 &amp; Bdiff==0 &amp; Cdiff==0),
                ifelse(nrow(df%&gt;%filter(Adiff==0 &amp; Bdiff==0)) != 0,
                df0&lt;-df%&gt;%filter(Adiff==0 &amp; Bdiff==0),
                "less then two exact match")
         ))
  
  tbl_df(df0[,1:5]) 
  
  # A tibble: 1 x 5
        A     B     C     D ID   
    &lt;int&gt; &lt;int&gt; &lt;int&gt; &lt;int&gt; &lt;chr&gt;
  1     4     4     3     3 G    
  </code></pre>
  
  <p>It works and found ID <strong>G</strong> but looks ugly to me. So the <strong>first question</strong> is - What would be recommended way to improve this? Are there any functions, packages or smth I'm missing?</p>
  
  <p><strong>Second question</strong> - I want to complicate condition.</p>
  
  <p>Imagine we have reference data set.</p>
  
  <pre><code>A B C D ID
  2 4 3 5  A
  5 1 3 5  B
  3 3 5 3  C
  4 3 1 5  D
  2 1 2 5  E
  5 4 4 5  F
  4 4 3 3  G
  2 1 5 5  H
  4 4 1 3  I
  4 2 2 2  J
  </code></pre>
  
  <p>Manual input is</p>
  
  <pre><code>A B C D ID
  4 4 2 2 man
  </code></pre>
  
  <p>Filtering rules should be following:</p>
  
  <ol>
  <li><p>If there is exact match in a whole row between <strong>reference</strong> table  and <strong>manual</strong> than extract this(those)  from reference and show me that row, if not then reduce number of matching columns from right to left until there is a match but not between less then two variables(columns A,B).</p></li>
  <li><p>From those rows where I have only two variable matches filter those which has ± 1 difference in  columns to the right. So I should have filtered case <strong>G</strong> and <strong>I</strong> from reference table from the example above.</p></li>
  </ol>
  
  <p><em>keep going the way I did above, I would do the following:</em></p>
  
  <pre><code>ifelse(nrow(df0%&gt;%filter(Cdiff %in% (-1:1) &amp; Ddiff %in% (-1:1)))&gt;0,
         df01 &lt;- df0%&gt;%filter(Cdiff %in% (-1:1) &amp; Ddiff %in% (-1:1)),
         ifelse(nrow(df0%&gt;%filter(Cdiff %in% (-1:1)))&gt;0,
                df01&lt;- df0%&gt;%filter(Cdiff %in% (-1:1)),
         "NA"))
  </code></pre>
  
  <p>It will be about 11 columns at the end, but I assume it doesn't matter so much.</p>
  
  <p>Keeping in mind this objective - how would you suggest to proceed?
  Thanks!</p>