title: Function of a list of data frames, to return also a data frame in R
body: <p>I have a <strong>list</strong> of <strong>data frames</strong> of the following form:</p>
  
  <pre><code>str(mylist)
  List of 2
   $ df1:'data.frame':    50 obs. of  4 variables:
    ..$ var1: num [1:50] 0.114 0.622 0.609 0.623 0.861 ...
    ..$ var2: num [1:50] -1.221 1.819 0.195 1.232 0.786 ...
    ..$ var3: num [1:50] -0.14 -1.003 -0.352 0.647 0.424 ...
    ..$ Y   : num [1:50] -1.24 1.38 0.3 2.44 2.09 ...
   $ df2:'data.frame':    50 obs. of  4 variables:
    ..$ var1: num [1:50] 0.114 0.622 0.609 0.623 0.861 ...
    ..$ var2: num [1:50] -1.221 1.819 0.195 1.232 0.786 ...
    ..$ var3: num [1:50] -0.14 -1.003 -0.352 0.647 0.424 ...
    ..$ Y   : num [1:50] -1.24 1.38 0.3 2.44 2.09 ...
   - attr(*, "class")= chr [1:2] "mi" "list"
  </code></pre>
  
  <p>I am trying to return the means of the data frames in the list corresponding to the correct variable, also as a data frame, to look like:</p>
  
  <pre><code>&gt; str(dfnew)
  'data.frame':   50 obs. of  4 variables:
   $ var1: num  0.114 0.622 0.609 0.623 0.861 ...
   $ var2: num  -1.221 1.819 0.195 1.232 0.786 ...
   $ var3: num  -0.14 -1.003 -0.352 0.647 0.424 ...
   $ Y   : num  -1.24 1.38 0.3 2.44 2.09 ...
  </code></pre>
  
  <p>So, something that does...</p>
  
  <pre><code>dfnew[1,1] &lt;- mean(mylist[[1]]$var1[1], mylist[[2]]$var1[1], na.rm=T)
  dfnew[2,1] &lt;- mean(mylist[[1]]$var1[2], mylist[[2]]$var1[2], na.rm=T)
  ...
  dfnew[50,1] &lt;- mean(mylist[[1]]$var1[50], mylist[[2]]$var1[50], na.rm=T)
  ...
  dfnew[1,2] &lt;- mean(mylist[[1]]$var2[1], mylist[[2]]$var2[1], na.rm=T)
  ...
  dfnew[50,4] &lt;- mean(mylist[[1]]$var4[50], mylist[[2]]$var4[50], na.rm=T)
  </code></pre>
  
  <p>I can see how I would do this with a for loop...</p>
  
  <p>...or by creating data frames of each variable, </p>
  
  <pre><code>var1df &lt;- cbind(df1$var1, df2$var1)
  var2df &lt;- cbind(df1$var2, df2$var2) # and if there are up to var1000?...
  ...
  dfnew$var1 &lt;- rowMeans(var1df)
  dfnew$var2 &lt;- rowMeans(var2df)
  ...
  </code></pre>
  
  <p>but that's more copying than I'd like and seems less than idiomatic R; so I'm trying to do it with one of the apply functions. </p>
  
  <p>Since this is a list, lapply seemed right, except that it seems to go across the wrong margin---that is, it's mean-ing within the list, rather than the mean across the lists.</p>
  
  <pre><code>&gt; lapply(mylist, FUN=mean)
  $df1
  [1] NA
  
  $df2
  [1] NA
  
  Warning messages:
  1: In mean.default(X[[1L]], ...) :
    argument is not numeric or logical: returning NA
  2: In mean.default(X[[2L]], ...) :
    argument is not numeric or logical: returning NA
  </code></pre>
  
  <p>There's no setting in lapply for the other margin, cross-list rather than in-list.</p>
  
  <p>And regular apply, which lets me set a margin is upset that this is a list, rather than a matrix or data frame.</p>
  
  <pre><code>&gt; apply(mylist, MARGIN = 2, FUN=mean)
  Error in apply(mylist, MARGIN = 2, FUN = mean) : 
    dim(X) must have a positive length
  </code></pre>
  
  <p>(My actual list has a lot more than 2 data frames, so a lot of the easier loopy or merge-y solutions get kind of hairy pretty quickly---or at least I'm too clumsy with the loop over getattribute stuff to know how to do it cleanly for length N.)</p>
  
  <p>Is there something I'm missing in one of the rapply, tapply, eapply, *apply functions that would solve this, or something in general I'm being dumb about?</p>
  
  <p><em>UPDATE</em></p>
  
  <p>Thanks everyone for the helpful answers.  I ran across this problem when I was testing out the Amelia libraries for multiple imputation and wanted to look at what the spread of the moments of the simulations were from the long-term means.  (The object they return is shaped like this, and has the properties described above of corresponding to the original data frame, and with no missing data.)</p>
  
  <p><a href="https://gist.github.com/mittenchops/9866880" rel="nofollow">Here's a gist</a> I put together fiddling with it.</p>
  
  <p>I like user20650's answer did not require additional copying (imputer2 in the gist), so when I started expanding onto a list of 1000, it became significantly faster than the ones that required merging new data frames.  </p>
  
  <p>What was kind of quirky and I haven't entirely resolved are that I was that running imputer1 versus imputer2 was producing values that looked identical, but for which a == b were false.  I assume a round-off issue.  </p>
  
  <p>I'm also still looking for a way to apply general functions like mean or sd over this construct (without copying) rather than computing them itemwise, but anyway my problem is solved and I'll leave that to another question.</p>