title: conditional string splitting in R (using tidyr)
body: <p>I have a data frame like this: </p>
  
  <pre><code>X &lt;- data.frame(value = c(1,2,3,4), 
                  variable = c("cost", "cost", "reed_cost", "reed_cost"))
  </code></pre>
  
  <p>I'd like to split the variable column into two; one column to indicate if the variable is a 'cost' and another column to indicate whether or not the variable is "reed". I cannot seem to figure out the right regex for the split (e.g. using tidyr)</p>
  
  <p>If my data were something nicer, say:</p>
  
  <pre><code>Y &lt;- data.frame(value = c(1,2,3,4), 
                  variable = c("adjusted_cost", "adjusted_cost", "reed_cost", "reed_cost"))
  </code></pre>
  
  <p>Then this is trivial with tidyr:</p>
  
  <pre><code>separate(Y, variable, c("Type", "Model"), "_")
  </code></pre>
  
  <p>and bingo. Instead, it looks like I need some kind of conditional statement to split on "_" if it is present, and otherwise split on the start of the pattern ("^"). </p>
  
  <p>I tried:</p>
  
  <pre><code>separate(X, variable, c("Policy-cost", "Reed"), "(?(_)_|^)", perl=TRUE)
  </code></pre>
  
  <p>but no luck.  I realize I cannot even split to an empty string successfully:</p>
  
  <pre><code>separate(X, variable, c("Policy-cost", "Reed"), "^", perl=TRUE)
  </code></pre>
  
  <p>how should I do this?  </p>
  
  <p><strong>Edit</strong> <em>Note</em> that this is a minimal example of a larger problem, in which there are many possible variables (not just <code>cost</code> and <code>reed_cost</code>) so I do not want to string match each one.  </p>
  
  <p>I am looking for a solution that splits arbitrary variables by the <code>_</code> pattern if present and otherwise splits them into a blank string and the original label.  </p>
  
  <p>I also realize I could just grep for the presence of <code>_</code> and then construct the columns manually.  That's fine if rather less elegant; it seems there should be a way to split on a string using a conditional that can return an empty string...</p>