title: Remove outlier rows by column and factor in R
body: <p>I am working with a data-frame in R. I have the following function which removes all rows of a data-frame <code>df</code> where, for a specified column index/attribute, the value at that row is outside mean (of column) plus or minus n*stdev (of column). </p>
  
  <pre><code>remove_outliers &lt;- function(df,attr,n){
    outliersgone &lt;- df[df[,attr]&lt;=(mean(df[,attr],na.rm=TRUE)+n*sd(df[,attr],na.rm=TRUE)) &amp; df[,attr]&gt;=(mean(df[,attr],na.rm=TRUE)-n*sd(df[,attr],na.rm=TRUE)),]
    return(outliersgone)
  }
  </code></pre>
  
  <p>There are two parts to my question.</p>
  
  <p>(1) My data-frame <code>df</code> also has a column 'Group', which specifies a class label. I would like to be able to remove outliers according to mean and standard deviation <em>within their group</em> within the column, i.e. organised by factor (within the column). So you would remove from the data-frame a row labelled with group A if, in the specified column/attribute, the value at that row is outside mean (of group A rows in that column) plus/minus n*stdev (of group A rows in that column). And the same for groups B, C, D, E, F, etc.</p>
  
  <p>How can I do this? (Preferably using only base R and dplyr.) I have tried to use <code>df %&gt;% group_by(Group)</code> followed by <code>mutate</code> but I'm not sure what to pass to mutate, given my function <code>remove_outliers</code> seems to require the whole data-frame to be passed into it (so it can return the whole data-frame with rows only <em>removed</em> based on the chosen attribute <code>attr</code>).</p>
  
  <p>I am open to hearing suggestions for changing the function <code>remove_outliers</code> as well, as long as they also return the whole data-frame as explained. I'd prefer solutions that avoid loops if possible (unless inevitable and no more efficient method presents itself in base R / dplyr).</p>
  
  <p>(2) Is there a straightforward way I could combine outlier considerations across multiple columns? e.g. remove from the dataframe <code>df</code> those rows which are outliers wrt at least $N$ attributes out of a specified vector of attributes/column indices (length≥N). or a more complex condition like, remove from the dataframe <code>df</code> those rows which are outliers wrt Attribute 1 <strong>and</strong> at least 2 of Attributes 2,4,6,8.</p>
  
  <p>(Ideally the definition of outlier would again be within-group within column, as specified in question 1 above, but a solution working in terms of just within column without considering the groups would also be useful for me.)</p>