title: Dataframes in a list; adding a new variable with name of dataframe
body: <p>I have a list of dataframes which I eventually want to merge while maintaining a record of their original dataframe name or list index. This will allow me to subset etc across all the rows. To accomplish this I would like to add a new variable 'id' to every dataframe, which contains the name/index of the dataframe it belongs to.</p>
  
  <p>Edit: "In my real code the dataframe variables are created from reading multiple files using the following code, so I don't have actual names only those in the  'files.to.read' list which I'm unsure if they will align with the dataframe order:</p>
  
  <pre><code>mylist &lt;- llply(files.to.read, read.csv)
  </code></pre>
  
  <p>A few methods have been highlighted in several posts:
  <a href="https://stackoverflow.com/questions/6399011/working-with-dataframes-in-a-list-drop-variables-add-new-ones">Working-with-dataframes-in-a-list-drop-variables-add-new-ones</a> and
  <a href="https://stackoverflow.com/questions/6253159/using-lapply-with-changing-arguments">Using-lapply-with-changing-arguments</a></p>
  
  <p>I have tried two similar methods, the first using the index list:</p>
  
  <pre><code>df1 &lt;- data.frame(x=c(1:5),y=c(11:15))
  df2 &lt;- data.frame(x=c(1:5),y=c(11:15))
  mylist &lt;- list(df1,df2)
  
  # Adds a new coloumn 'id' with a value of 5 to every row in every dataframe.
  # I WANT to change the value based on the list index.
  mylist1 &lt;- lapply(mylist, 
      function(x){
          x$id &lt;- 5
          return (x)
      }
  )
  #Example of what I WANT, instead of '5'.
  #&gt; mylist1
  #[[1]]
    #x  y id
  #1 1 11  1
  #2 2 12  1
  #3 3 13  1
  #4 4 14  1
  #5 5 15  1
  #
  #[[2]]
    #x  y id
  #1 1 11  2
  #2 2 12  2
  #3 3 13  2
  #4 4 14  2
  #5 5 15  2
  </code></pre>
  
  <p>The second attempts to pass the names() of the list.</p>
  
  <pre><code># I WANT it to add a new coloumn 'id' with the name of the respective dataframe
  # to every row in every dataframe.
  mylist2 &lt;- lapply(names(mylist), 
      function(x){
          portfolio.results[[x]]$id &lt;- "dataframe name here"
          return (portfolio.results[[x]])
      }
  )
  #Example of what I WANT, instead of 'dataframe name here'.
  # mylist2
  #[[1]]
    #x  y id
  #1 1 11  df1
  #2 2 12  df1
  #3 3 13  df1
  #4 4 14  df1
  #5 5 15  df1
  #
  #[[2]]
    #x  y id
  #1 1 11  df2
  #2 2 12  df2
  #3 3 13  df2
  #4 4 14  df2
  #5 5 15  df2
  </code></pre>
  
  <p>But the names() function doesn't work on a list of dataframes; it returns NULL.
  Could I use seq_along(mylist) in the first example.</p>
  
  <p>Any ideas or better way to handle the whole "merge with source id"</p>
  
  <p><strong>Edit - Added Solution below:</strong> I've implemented a solution using Hadleys suggestion and Tommy’s nudge which looks something like this.  </p>
  
  <pre><code>files.to.read &lt;- list.files(datafolder, pattern="\\_D.csv$", full.names=FALSE)
  mylist &lt;- llply(files.to.read, read.csv)
  all &lt;- do.call("rbind", mylist)
  all$id &lt;- rep(files.to.read, sapply(mylist, nrow))
  </code></pre>
  
  <p>I used the files.to.read vector as the id for each dataframe</p>
  
  <p>I also changed from using merge_recurse() as it was very slow for some reason.  </p>
  
  <pre><code> all &lt;- merge_recurse(mylist)
  </code></pre>
  
  <p>Thanks everyone.</p>