title: R - Subseting data by searching a list with wildcards across multiple columns
body: <p>I am a relatively new R user who is doing analysis of administrative health data.</p>
  
  <p>This community has been a great help at advancing my own understanding of R and its' functions - however after spending an entire day stuck with this issue, and without being able to find a solution (thus far), I have decided to post for the first time. </p>
  
  <p>Briefly,</p>
  
  <p>My data set contains multiple diagnostic vectors (25 columns in total) can include a variety of 'diagnostic codes' or be NA.</p>
  
  <p>Each row corresponds to one encounter with the health system (which may include multiple diagnostic codes - up to the 25), however I am only interested in the encounters that have a diagnostic code (in one of the 25 fields) for a particular condition of interest.</p>
  
  <p>The challenge I am having is that the disease diagnostic codes I want to search for correspond to the beginning of the specific diagnostic codes that are in the actual data. (e.g. I want to find all codes that start with M16 and M17 - and these in the data will appear as M161 or M1611, etc.) </p>
  
  <p>I have found some code through this site which has allowed me to search the 25 diagnostic code fields in the data, looking for a specified list of diagnostic codes of interest, and subset the data to only those encounters where the codes of interest occur.</p>
  
  <p>The issue I am having is that I have to specify the codes exactly, as I have not been able to work a wildcard into the function to search for any diagnostic code (eg. M1611, M1622) using just the first few characters (e.g. M16).</p>
  
  <p>I have created some simple data to replicate what I CAN do right now. What I would like to be able to do is to use a list codes that I specify (e.g. M16, M17 with a wildcard operator to come up with the same outcome ('data-subset').</p>
  
  <p>I suspect this will involve grep, but for the life of me I have not been able to come up with a way of doing so. Any help would be greatly appreciated, and I hope that I have provided a clear enough question and code.</p>
  
  <pre><code>#make a simple data set
  id = c(1,2,3,4,5,6)
  pr1 = c("M151", "M141", "M161", "M177", "M197", "M200")
  pr2 = c("M100", "M101", "M120", "M135", "M144", "M190")
  pr3 = c("M210", "M205", "M167", "M121", "M166", "M174")
  data &lt;-  data.frame(id,pr1,pr2,pr3)
  
  #list of columns to search
  list &lt;- names(data)[2:4]
  
  #codes of interest
  codes &lt;- c("M161","M174","M177","M167","M166")
  
  # subset the data to include only those that have a code of interest
  data_subset &lt;- data[apply(apply(as.matrix(data[list]), c(1,2), `%in%`, codes), 1, any),]
  </code></pre>
  
  <p>Thank you in advance for your help.</p>
  
  <p>Edit 1 for clarity - my ultimate goal would be to produce an output as follows:</p>
  
  <pre><code>row.names   id  pr1     pr2     pr3
  3            3  M161    M120    M167
  4            4  M177    M135    M121
  5            5  M197    M144    M166
  6            6  M200    M190    M174
  </code></pre>
  
  <p>It retains only the rows from the original set that had a value of interest, but otherwise maintains the structure of the data.frame. As mentioned below - an added challenge is I am working in a secure research environment where I have no internet access, and thus can not install packages at will...</p>
  
  <p>Edit 2: Another solution (via a brilliant friend) in addition to that one posted below:</p>
  
  <pre><code># regexes that we want to match
  regexcodes &lt;- c("^M16", "^M17")
  
  # subset the data to include only those that have a code of interest
  data_subset &lt;- data[apply(apply(as.matrix(data[list]), c(1,2), function(u){
    # u corresponds to the actual string
  
    # this combines your regex into the following: "^M16|^M17" - it is basically
    # just an OR operator in a regex
    combined_regex &lt;- paste(regexcodes,collapse="|")
  
    # grepl returns true if u matches the regex
    grepl(combined_regex, u, perl=TRUE)
  }), 1, any),]
  </code></pre>