title: simplify lists recursively using unlist
body: <p>Consider a case like this:</p>
  
  <pre><code>xml_list &lt;- list(
    a = "7",
    b = list("8"),
    c = list(
      c.a = "7",
      c.b = list("8"), 
      c.c = list("9", "10"),
      c.d = c("11", "12", "13")),
    d = c("a", "b", "c"))
  </code></pre>
  
  <p>what I'm looking for is a way of how to simplify this construct recursively such that <code>unlist</code> is called on any <code>list</code> of length 1. The expected result for above example would look like:</p>
  
  <pre><code>list(
    a = "7",
    b = "8",
    c = list(
      c.a = "7",
      c.b = "8", 
      c.c = list("9", "10"),
      c.d = c("11", "12", "13")),
   d = c("a", "b", "c"))
  </code></pre>
  
  <p>I have dabbled with <code>rapply</code>, but that explicitly operates on <code>list</code>-members that are <strong>NOT</strong> lists themselves, so wrote the following:</p>
  
  <pre><code>library(magrittr)
  clean_up_list &lt;- function(xml_list){
    xml_list %&gt;%
      lapply(
        function(x){
          if(is.list(x)){
            if(length(x) == 1){
              x %&lt;&gt;%
                unlist()
            } else {
              x %&lt;&gt;%
                clean_up_list()
            }
          }
          return(x)
        })
  }
  </code></pre>
  
  <p>This, however, I can't even test, as <code>Error: C stack usage  7969588 is too close to the limit</code> (at least on lists that I terminally want to process).</p>
  
  <p>Digging deeper (and after mulling over @Roland's response), I came up with a solution that utilizes <code>purrr</code>-goodness, reversely iterates over list depth and <strong>NEARLY</strong> does what I want:</p>
  
  <pre><code>clean_up_list &lt;- function(xml_list)
  {
    list_depth &lt;- xml_list %&gt;%
      purrr::vec_depth()
    for(dl in rev(sequence(list_depth)))
    {
      xml_list %&lt;&gt;%
        purrr::modify_depth(
          .depth = dl,
          .ragged = TRUE,
          .f = function(x)
          {
            if(is.list(x) &amp;&amp; length(x) == 1 &amp;&amp; length(x[[1]]) == 1)
            {
              unlist(x, use.names = FALSE)
            } else {
              x
            }
          })
    }
    return(xml_list)
  }
  </code></pre>
  
  <p>This appears to work as intended even for lists of the depth I'm dealing with <strong>BUT</strong> elements that used to be vectors (like <code>c.d</code> and <code>d</code> in the example) now are converted to <code>lists</code>, which defeats the purpose ... any further insight?</p>