[med-svn] [r-cran-plyr] 01/05: Imported Upstream version 1.8.1

Charles Plessy plessy at moszumanska.debian.org
Tue May 20 11:28:12 UTC 2014


This is an automated email from the git hooks/post-receive script.

plessy pushed a commit to branch master
in repository r-cran-plyr.

commit ee423f5ba80e6ca3bf7d321424e3145605c8e06f
Author: Charles Plessy <plessy at debian.org>
Date:   Tue May 20 20:10:33 2014 +0900

    Imported Upstream version 1.8.1
---
 DESCRIPTION                     |  47 +--
 LICENSE                         |   2 +
 MD5                             | 272 +++++++------
 NAMESPACE                       |   4 +
 NEWS                            | 879 +++++++++++++++++++++-------------------
 R/RcppExports.R                 |  35 ++
 R/colwise.r                     |   1 -
 R/count.r                       |   2 +-
 R/id.r                          |   4 +-
 R/idataframe.r                  |  10 +-
 R/indexed-array.r               |   6 +-
 R/indexed-data-frame.r          |   2 +-
 R/indexed.r                     |  10 +-
 R/l_ply.r                       |   2 +
 R/ldply.r                       |  13 +-
 R/list-to-array.r               |   2 +-
 R/list-to-dataframe.r           |  17 +-
 R/loop-apply.r                  |  13 -
 R/plyr.r                        |   1 +
 R/quote.r                       |  28 +-
 R/r_ply.r                       |  20 +-
 R/raply.r                       |   9 +-
 R/rbind-fill.r                  | 205 +++++++---
 R/rdply.r                       |  35 +-
 R/revalue.r                     |   2 +-
 R/rlply.r                       |  85 +++-
 R/round-any.r                   |   4 +-
 R/split-indices.r               |  18 -
 R/splitter-d.r                  |   1 +
 R/summarise.r                   |  11 +-
 README.md                       |   2 +
 inst/tests/test-array.r         |   8 +-
 inst/tests/test-count.r         |  14 +
 inst/tests/test-data-frame.r    |  13 +
 inst/tests/test-join.r          |  19 +
 inst/tests/test-list.r          |  11 +
 inst/tests/test-mutate.r        |   4 +-
 inst/tests/test-ninteraction.r  |   5 +
 inst/tests/test-parallel.r      |  12 +-
 inst/tests/test-rbind.r         | 168 +++++++-
 inst/tests/test-replicate.r     |   6 +
 inst/tests/test-revalue.r       |  17 +
 inst/tests/test-rply.r          | 146 +++++++
 inst/tests/test-simplify-df.r   |  35 +-
 inst/tests/test-split-indices.r |  11 +-
 man/a_ply.Rd                    |  26 +-
 man/aaply.Rd                    |  42 +-
 man/adply.Rd                    |  27 +-
 man/alply.Rd                    |  39 +-
 man/amv_dim.Rd                  |   5 +-
 man/amv_dimnames.Rd             |  12 +-
 man/arrange.Rd                  |  15 +-
 man/as.data.frame.function.Rd   |  13 +-
 man/as.list.split.Rd            |   6 +-
 man/as.quoted.Rd                |  19 +-
 man/baseball.Rd                 |  16 +-
 man/colwise.Rd                  |  16 +-
 man/compact.Rd                  |   5 +-
 man/count.Rd                    |  27 +-
 man/create_progress_bar.Rd      |  42 +-
 man/d_ply.Rd                    |  26 +-
 man/daply.Rd                    |  34 +-
 man/ddply.Rd                    |  29 +-
 man/defaults.Rd                 |   6 +-
 man/desc.Rd                     |   6 +-
 man/dims.Rd                     |   5 +-
 man/dlply.Rd                    |  29 +-
 man/each.Rd                     |  12 +-
 man/empty.Rd                    |   5 +-
 man/eval.quoted.Rd              |   8 +-
 man/failwith.Rd                 |  11 +-
 man/get-split.Rd                |   5 +-
 man/here.Rd                     |  12 +-
 man/id.Rd                       |  17 +-
 man/id_var.Rd                   |   5 +-
 man/idata.frame.Rd              |  19 +-
 man/indexed_array.Rd            |   7 +-
 man/indexed_df.Rd               |   6 +-
 man/is.discrete.Rd              |   5 +-
 man/is.formula.Rd               |   6 +-
 man/isplit2.Rd                  |   5 +-
 man/join.Rd                     |  44 +-
 man/join.keys.Rd                |   7 +-
 man/join_all.Rd                 |   5 +-
 man/l_ply.Rd                    |  25 +-
 man/laply.Rd                    |  38 +-
 man/ldply.Rd                    |  32 +-
 man/liply.Rd                    |  14 +-
 man/list_to_array.Rd            |   8 +-
 man/list_to_dataframe.Rd        |  17 +-
 man/list_to_vector.Rd           |   8 +-
 man/llply.Rd                    |  29 +-
 man/loop_apply.Rd               |   7 +-
 man/m_ply.Rd                    |  36 +-
 man/maply.Rd                    |  40 +-
 man/mapvalues.Rd                |  25 +-
 man/match_df.Rd                 |  33 +-
 man/mdply.Rd                    |  36 +-
 man/mlply.Rd                    |  36 +-
 man/mutate.Rd                   |  23 +-
 man/name_rows.Rd                |  13 +-
 man/names.quoted.Rd             |  10 +-
 man/nunique.Rd                  |   6 +-
 man/ozone.Rd                    |  20 +-
 man/plyr.Rd                     |  34 +-
 man/print.quoted.Rd             |   5 +-
 man/print.split.Rd              |   5 +-
 man/progress_none.Rd            |  13 +-
 man/progress_text.Rd            |  16 +-
 man/progress_time.Rd            |  12 +-
 man/progress_tk.Rd              |  15 +-
 man/progress_win.Rd             |  14 +-
 man/quickdf.Rd                  |   9 +-
 man/quoted.Rd                   |  28 +-
 man/r_ply.Rd                    |  17 +-
 man/raply.Rd                    |  27 +-
 man/rbind.fill.Rd               |  33 +-
 man/rbind.fill.matrix.Rd        |  40 +-
 man/rdply.Rd                    |  31 +-
 man/reduce_dim.Rd               |   5 +-
 man/rename.Rd                   |   5 +-
 man/revalue.Rd                  |  19 +-
 man/rlply.Rd                    |  24 +-
 man/round_any.Rd                |   5 +-
 man/splat.Rd                    |  15 +-
 man/split_indices.Rd            |  17 +-
 man/split_labels.Rd             |   6 +-
 man/splitter_a.Rd               |  30 +-
 man/splitter_d.Rd               |  32 +-
 man/strip_splits.Rd             |  12 +-
 man/summarise.Rd                |  17 +-
 man/take.Rd                     |   5 +-
 man/true.Rd                     |   9 +-
 man/try_default.Rd              |  11 +-
 man/tryapply.Rd                 |   6 +-
 man/unrowname.Rd                |   5 +-
 man/vaggregate.Rd               |  20 +-
 src/RcppExports.cpp             |  39 ++
 src/loop-apply.c                |  25 --
 src/loop-apply.cpp              |  23 ++
 src/split-numeric.c             |  40 --
 src/split-numeric.cpp           |  34 ++
 142 files changed, 2338 insertions(+), 1656 deletions(-)

diff --git a/DESCRIPTION b/DESCRIPTION
index e22eb95..993d2c9 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,38 +1,27 @@
 Package: plyr
 Type: Package
 Title: Tools for splitting, applying and combining data
-Version: 1.8
+Version: 1.8.1
 Author: Hadley Wickham <h.wickham at gmail.com>
 Maintainer: Hadley Wickham <h.wickham at gmail.com>
-Description: plyr is a set of tools that solves a common set of
-        problems: you need to break a big problem down into manageable
-        pieces, operate on each pieces and then put all the pieces back
-        together.  For example, you might want to fit a model to each
-        spatial location or time point in your study, summarise data by
-        panels or collapse high-dimensional arrays to simpler summary
-        statistics. The development of plyr has been generously
-        supported by BD (Becton Dickinson).
+Description: plyr is a set of tools that solves a common
+    set of problems: you need to break a big problem down
+    into manageable pieces, operate on each pieces and then
+    put all the pieces back together.  For example, you
+    might want to fit a model to each spatial location or
+    time point in your study, summarise data by panels or
+    collapse high-dimensional arrays to simpler summary
+    statistics. The development of plyr has been generously
+    supported by BD (Becton Dickinson).
 URL: http://had.co.nz/plyr
 Depends: R (>= 2.11.0)
-Suggests: abind, testthat (>= 0.2), tcltk, foreach, doMC, itertools,
-        iterators
-License: MIT
+Imports: Rcpp (>= 0.11.0)
+LinkingTo: Rcpp
+Suggests: abind, testthat, tcltk, foreach, doMC, itertools, iterators
+License: MIT + file LICENSE
 LazyData: true
-Collate: 'dimensions.r' 'id.r' 'indexed-array.r' 'indexed-data-frame.r'
-        'indexed.r' 'join.r' 'loop-apply.r' 'progress.r' 'quote.r'
-        'split-indices.r' 'split.r' 'utils.r' 'utils-functional.r'
-        'data.r' 'plyr.r' 'parallel.r' 'progress-time.r' 'a_ply.r'
-        'aaply.r' 'adply.r' 'alply.r' 'd_ply.r' 'daply.r' 'ddply.r'
-        'dlply.r' 'l_ply.r' 'laply.r' 'llply.r' 'm_ply.r' 'maply.r'
-        'mdply.r' 'mlply.r' 'r_ply.r' 'raply.r' 'rdply.r' 'rlply.r'
-        'liply.r' 'ldply.r' 'arrange.r' 'colwise.r' 'count.r'
-        'data-frame.r' 'defaults.r' 'each.r' 'here.r' 'match-df.r'
-        'mutate.r' 'name-rows.r' 'quickdf.r' 'rename.r' 'revalue.r'
-        'round-any.r' 'splat.r' 'strip-splits.r' 'summarise.r' 'take.r'
-        'try.r' 'vaggregate.r' 'idataframe.r' 'join-all.r'
-        'list-to-array.r' 'list-to-dataframe.r' 'list-to-vector.r'
-        'rbind-fill-matrix.r' 'rbind-fill.r' 'splitter-a.r'
-        'splitter-d.r'
-Packaged: 2012-12-05 21:45:23 UTC; hadley
+Roxygen: list(wrap = FALSE)
+Packaged: 2014-02-26 16:06:36 UTC; hadley
+NeedsCompilation: yes
 Repository: CRAN
-Date/Publication: 2012-12-06 08:59:31
+Date/Publication: 2014-02-26 17:25:17
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..b47c7a0
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,2 @@
+YEAR: 2014
+COPYRIGHT HOLDER: Hadley Wickham
diff --git a/MD5 b/MD5
index 3a36dfd..9a458da 100644
--- a/MD5
+++ b/MD5
@@ -1,13 +1,15 @@
-9b663d59b979371b6a101f6c0514a156 *DESCRIPTION
-2fa4b4cc08cfe312801d77dab73ebc3a *NAMESPACE
-37f7eb2a168c9ca03d9856e20387903f *NEWS
+14208015e2a45aa7983c4fd57b10d60a *DESCRIPTION
+7bb6b2019939096672a443d7b6e80d5b *LICENSE
+e6adf1c94f4dd5bf55de1474a328ce1c *NAMESPACE
+a72fcf3e7dee2c4d1338093ad79c984e *NEWS
+edba520097aa39d8caa24b811ac283bc *R/RcppExports.R
 b30083458b44dd0ebdb6573f81cbaf09 *R/a_ply.r
 051d8e915e9d4fd1d37baba2c8540cd3 *R/aaply.r
 7518e52d3fffabe64480674f0c0841fb *R/adply.r
 effba88914db9ef403f64b4b0d00a8d5 *R/alply.r
 27850e8a34d803a77059aee92fe98a51 *R/arrange.r
-dbaeb0f7ac128903161538fa22f26da7 *R/colwise.r
-bab38e28e3e345d2bea2ee72f682e220 *R/count.r
+6eddac05a5943b98bcd29462cddc5390 *R/colwise.r
+a3b498c0d8ed5f7e1a390f9efbbef4f4 *R/count.r
 f05b9167d486f77d2eaecaee67eb416f *R/d_ply.r
 fb6dcb53dca0a98cf6a1da120c2c478d *R/daply.r
 9ec2eb1767f801a2f9783af803cac212 *R/data-frame.r
@@ -18,22 +20,21 @@ a18f14f7e0a6f50360586504d1311227 *R/dimensions.r
 fabcd1e2c375a3861200a934b924074a *R/dlply.r
 099f05c40f96cc0e0e9bc5bb1e33cfac *R/each.r
 dcaa350d0ab003f6ad12e4d18f5eef90 *R/here.r
-6573fcf86598a272fe60ce9cd86d7015 *R/id.r
-8d38e8274a1e6e549456888e314509e4 *R/idataframe.r
-d31d1c394a815adaa016acb562de0842 *R/indexed-array.r
-2dd51053e2dd003d3c46ed3a2f6fa459 *R/indexed-data-frame.r
-0cc320306148b4c9e00cc7ead82cbd12 *R/indexed.r
+acd41bddf854e33968ccb0b2fe596f0a *R/id.r
+89091436b8f027be1dda58993b1f82d8 *R/idataframe.r
+fc14994abc7f86af89a188295a2dc5f5 *R/indexed-array.r
+229267201ee89bc089a3b3f7c6fba5cb *R/indexed-data-frame.r
+9c4c3d5f8a5d1acfbc1d7a98ea6ee99c *R/indexed.r
 aeb3707b4a7ffae8af0e9237f3f67e72 *R/join-all.r
 f4572136e8a85fdd0bd77a2216bb557d *R/join.r
-154acfdcc1ea3b63cc80151d69d8c734 *R/l_ply.r
+a4a9b4bbc2be5c7f757f41cecf8bfccf *R/l_ply.r
 49db6bd50575429654a36aec5fca75dc *R/laply.r
-7e06f4ff7fba5ce7e93c39331e7b2fdd *R/ldply.r
+e881eda9763eaa9738d24514d2124d92 *R/ldply.r
 61a3bea3cc93368b6ac6f453a0ae3744 *R/liply.r
-0a2810798164088dda8d4e31e0891ff2 *R/list-to-array.r
-ab9cd1a82d137c652e71324eb25dec70 *R/list-to-dataframe.r
+aee2e6c562f11df1c6e5485e973a9b86 *R/list-to-array.r
+d2d461c086c0a59c3e8bcdc2f5760086 *R/list-to-dataframe.r
 0235ddca614287ca137a2a5ec80b6ecc *R/list-to-vector.r
 fe85fcdb0225eb6ac7812ff3a9aac5ba *R/llply.r
-a111fc796dbb2bb6d98e8c7a44a3cf16 *R/loop-apply.r
 138f6c83d529bbf8c68f8830d7081570 *R/m_ply.r
 233c43c50f214fb7b6cb4da744bda204 *R/maply.r
 8c2d4fbdc639835b6a7d5fa2f01f0026 *R/match-df.r
@@ -42,152 +43,153 @@ f8952eb7391ea62de7b94494f2734d23 *R/mlply.r
 fb0da67095913ebc3e7dc368e6410ca2 *R/mutate.r
 7787cd67a1bd78ff9b8169cc55015e3c *R/name-rows.r
 56cf70c7362e1f76ddf82672b8444b5c *R/parallel.r
-65cad21d5e61b3c53af0278540715656 *R/plyr.r
+e535a17dfafddbb183e94b5ceb86554b *R/plyr.r
 eb8917263bad12770cd32445403be25c *R/progress-time.r
 b413617b9c819a43a15cc1b450b88cdc *R/progress.r
 87b4723fec09c203ea9c98373d87cb4b *R/quickdf.r
-1baea22f9ff11a3cafa901689d1cc1bc *R/quote.r
-14fe46cf226a4774cb05fc4e7aede76f *R/r_ply.r
-c5b6f32a7d4ceba0b201ed58d6d3b989 *R/raply.r
+fcb40695275ede3f638b9f0ff27d0d0f *R/quote.r
+d2d78e4a2a595733f0f9b15b50a36ce0 *R/r_ply.r
+9280ab29ec7162e29f330717de5ee90e *R/raply.r
 9f5486ed284127abbdd22cd9ce783f4f *R/rbind-fill-matrix.r
-d772aca0b29a04520372a22ec6c6a474 *R/rbind-fill.r
-746027418d6df16e5ab63e10aafe7772 *R/rdply.r
+ac1b576c6e477408d0d1895c098c6721 *R/rbind-fill.r
+23dedcd1fbbdea0102867231c860ce1d *R/rdply.r
 483e90a4ad2aebccc73c5ddd1b32503d *R/rename.r
-4921126fc5506e7ab00ac924cf937cc2 *R/revalue.r
-d44675874eccaa49892e11a11ea9ebba *R/rlply.r
-ca9e3ea0a3d9e47854bfcb533fdad53b *R/round-any.r
+ddd658679cca81363137627bfe7edaa2 *R/revalue.r
+1eacd06285c8f96a51679bff03169133 *R/rlply.r
+b0d8beec3c1c5cab302e9454c8b16d33 *R/round-any.r
 7369a7d69027736f1e62f0f49fa8aed6 *R/splat.r
-cef16fac9a4a53ffa46169dfd3ebcc91 *R/split-indices.r
 29e4abb6bc1f7561ff08c08554ccb58c *R/split.r
 c80b8aa598ab1329699f201d414a3ef6 *R/splitter-a.r
-ecbe80157dbd628a6c741f90c56d0fcb *R/splitter-d.r
+75bdf5f45ad79a232c5da028f3206489 *R/splitter-d.r
 c3f4bc5baaa2be00a96fae50f235097a *R/strip-splits.r
-d6dbd2b5909f72f5ec28c6e3cff1c3ed *R/summarise.r
+cb3527ae83472efb1318bbe10286df0f *R/summarise.r
 632a3d93a68172b1350d5f23151c0f0c *R/take.r
 d1c1587c3f3056b2a17c6085a1e0d8e2 *R/try.r
 d2189ca6934b505c385b70e66165e298 *R/utils-functional.r
 e7f9e2adc241a3f9ad0ab2e26e2aedb1 *R/utils.r
 3d73325ab592dff535a8e7bd8e869967 *R/vaggregate.r
-8f61b6486addfcd6b8b079cd6add0e9c *README.md
+67361b19bae482e50e4c7cba6c1eab21 *README.md
 9b2d63a08f6c4d1718642d2c904c230a *data/baseball.rda
 12d6f72bbc8c97a10e7c4c235aab3ae3 *data/ozone.rda
 c064ec8464bce62b7862acec50e8475b *inst/CITATION
 d564b7820ed6c9598ef0e9f39913a4dc *inst/tests/quickdf.r
-71b3d690155f10491a0c36295fcca10a *inst/tests/test-array.r
-9df6700af6e72c3afcea6d488917972e *inst/tests/test-count.r
-64843ae8890dedb58491b0c68b7d5e41 *inst/tests/test-data-frame.r
+44840e515539c5a48d5dd6fc74b14d38 *inst/tests/test-array.r
+07841d0cbecdfb3efb15d1e00cb37dc0 *inst/tests/test-count.r
+4439677af6964bb0f16651e963743dc5 *inst/tests/test-data-frame.r
 570589b2d8f6a5e7a5a9292bde0255c3 *inst/tests/test-empty.r
 22fb32944156a59fb79d4b9b9185f685 *inst/tests/test-idf.r
-edcb617aef78240a4aab68b4d9eef8b9 *inst/tests/test-join.r
-de3b9fe325bde5a4d7ae4fee2b124dd4 *inst/tests/test-list.r
+7ec1ca26c51cd4b3ccdafe47b7ffa2c3 *inst/tests/test-join.r
+d425059aa1aca6b0a1b89096771bbfae *inst/tests/test-list.r
 e4a2dbcd3e829d98895ac697916dbfc5 *inst/tests/test-mapply.r
-f0b164f2304fbef1573b5859032a81ba *inst/tests/test-mutate.r
-b4ffb0e168d64cfb2337467d5949bb87 *inst/tests/test-ninteraction.r
-148c66709e0a612190930417b891569e *inst/tests/test-parallel.r
+72e5df4f944d454f308efb98a475304c *inst/tests/test-mutate.r
+083da5f76a2638553a1edfed5e8d00da *inst/tests/test-ninteraction.r
+d37844e33d7c43e0968878d6c1727be7 *inst/tests/test-parallel.r
 5edbe06f3ef5ca4afebae668d5f72394 *inst/tests/test-progress.r
 af8f0160f64ccc89202dd1c6fd4255ad *inst/tests/test-quote.r
 d6275e43a3f6b046422f88c65323bc26 *inst/tests/test-rbind.matrix.r
-680dccdcc148e4b95ca0d9216e2d8289 *inst/tests/test-rbind.r
+fd919c36a8a6db23ca1ba6bdf1830f4e *inst/tests/test-rbind.r
 0db4452cb3b1aebc91a230ec4152d8b4 *inst/tests/test-rename.r
-92f8e58ba0c83bb0c1c3e333bc3ffe55 *inst/tests/test-replicate.r
-f2b44485ec854cfc9e68c44d5fbc630b *inst/tests/test-revalue.r
-3b4322ac83b50f5a1a370c07c8f5d92b *inst/tests/test-simplify-df.r
+7d96fa52964d7d9ec5369496484455b0 *inst/tests/test-replicate.r
+d8bff3eef2ff9eb85896d7850f65b892 *inst/tests/test-revalue.r
+73bcf4bb95c4259a1a5287d09af225e5 *inst/tests/test-rply.r
+fa78b5aca1c58a0e9ca7c6dcf4a8b81d *inst/tests/test-simplify-df.r
 8333352212f7d58b1e53ce26a60afb5f *inst/tests/test-split-data-frame.r
-fe3ec6775a168e58a03f54a4b2324596 *inst/tests/test-split-indices.r
+1d076e075a65f446945ae732ddfc50a6 *inst/tests/test-split-indices.r
 9dd79657465c4e2ab72d4209f047854b *inst/tests/test-split-labels.r
 dc9ed90dded1449345037dce24ba8c79 *inst/tests/test-summarise.r
-49ea637ae8cb2562fe7b5c102ac10559 *man/a_ply.Rd
-ce52ec32036bd6ddf088b33155bdf7b4 *man/aaply.Rd
-fc292562290ffb4d124ff2907090b5ce *man/adply.Rd
-9e97ae53b984ab36fba6e004295a085e *man/alply.Rd
-dfff8dc0d6841b6b437875342bb784dd *man/amv_dim.Rd
-144600b773ec891d73e4a109b60b153b *man/amv_dimnames.Rd
-8ab0a5af25222d56a4315c092796f9d4 *man/arrange.Rd
-30bf0f3c6fc678900168bac2f015ded6 *man/as.data.frame.function.Rd
-2a5482715255383f335065d8a6d7d8ae *man/as.list.split.Rd
-0efc6aa43e0d9eb9eeb89fee250e4c96 *man/as.quoted.Rd
-de25bd94213ee4dd760b525ddefd45b2 *man/baseball.Rd
-10a6252651f974b732dd6c1af3b14467 *man/colwise.Rd
-27e6c58afc383e8f66bb02568a7bd007 *man/compact.Rd
-938c1d38daf1e20f1dec95862ab78be4 *man/count.Rd
-06c0a8d42784a7f307b08623b9c895a3 *man/create_progress_bar.Rd
-63408510df419a00edd6f6467572bd96 *man/d_ply.Rd
-ea421a939afbb16459398b1118fa86a7 *man/daply.Rd
-1898a193a4ddc66e3a5bfd1eac362f22 *man/ddply.Rd
-598e17cddf0197cd109324b6e793e2a7 *man/defaults.Rd
-6b88af2bb271b3a0c4f4e7317deb6ab7 *man/desc.Rd
-3715aa08855964d4330e187d7d486b16 *man/dims.Rd
-76221834bab7a319e98439e8e77ef9c7 *man/dlply.Rd
-fdf29018b750e2f3d94a75b9c87d0170 *man/each.Rd
-15b8fca1da5a1d13124297ff1a69036b *man/empty.Rd
-c372bd8f82bf880e2e91f4b5dbb55b6c *man/eval.quoted.Rd
-90421f580f1c9692f41f2422e014d584 *man/failwith.Rd
-7ae0a790c8276dcee9e0cf627003ffbd *man/get-split.Rd
-6397abb97a76e9f28bb62f44827b2777 *man/here.Rd
-2c17345f244448c628b8616d743c5002 *man/id.Rd
-c7b3d72280561f2fe93371bc1a37061d *man/id_var.Rd
-485099a413e4731b7cf14a4184744e73 *man/idata.frame.Rd
-840f66765d63837a329a6297926ab66e *man/indexed_array.Rd
-06dc046ae9c663debbe953e9f49ba7e1 *man/indexed_df.Rd
-85ead63b1217af3ef8fdfe007e01cfe4 *man/is.discrete.Rd
-b6e6fad38ecf71f9333b8ac9520786bb *man/is.formula.Rd
-bb37d48d1c298ea013748f1c01866975 *man/isplit2.Rd
-b396bc6d3cc7d38555911ce1e63250e9 *man/join.Rd
-ec9d2d7fc41be3fa106cc534222426d0 *man/join.keys.Rd
-97587fef54e4fdf7effc02740a4f0a9e *man/join_all.Rd
-dfe4750fdf4923e3104ffaaf131776c7 *man/l_ply.Rd
-16d71e2c8e67a223d8f84b0f7ec499be *man/laply.Rd
-934ef2296ac98ee0e0cc4e39f96e69d9 *man/ldply.Rd
-7516a16cb60cf27566dc51c0046fc138 *man/liply.Rd
-629de84d5032c86d038012340ba02b8f *man/list_to_array.Rd
-4a476049a866905659cdf070dd9727a2 *man/list_to_dataframe.Rd
-862688bd52d3cab5daf4d8f1511f138b *man/list_to_vector.Rd
-c230664131ce3aacccdaaf4ddb68ec35 *man/llply.Rd
-1d1821666ac2124fc476fa512abb8200 *man/loop_apply.Rd
-6cfa6ff8f8e9dd5a84fc7c770425fc9f *man/m_ply.Rd
-3fed62ee065293b23f7b079c1d7f497f *man/maply.Rd
-499659e175a892fe417828493a319b78 *man/mapvalues.Rd
-bd78c0cdf780b4bada59979f2ae1b99c *man/match_df.Rd
-a8238f408548022f6d4848226291e0cf *man/mdply.Rd
-bc809f5e6aa94fcb3df99d733503b284 *man/mlply.Rd
-2d0c92444909eb8f009df5f3e21bb091 *man/mutate.Rd
-62c79cc73057d579d576328ae58a4d25 *man/name_rows.Rd
-c559d1372836dbd9b8d603c7631fa023 *man/names.quoted.Rd
-5008ea2c544983f5a8ad9b51367ee642 *man/nunique.Rd
-d2710642ac44b64f9f43fd08f8237e15 *man/ozone.Rd
-9685e33922cf6f5a69c55af08205cc72 *man/plyr.Rd
-4294d4956a0321e27c5e38799bf20613 *man/print.quoted.Rd
-73a288e900f81f9cbb37dd7f323c4946 *man/print.split.Rd
-f7bff61b6aa741fd33c61909c57ac5be *man/progress_none.Rd
-75050a56b20299646c38082b34c3d97c *man/progress_text.Rd
-c2373c71158781240ce95d96294f6e27 *man/progress_time.Rd
-2ca810721d1ea1db287d333158a1d692 *man/progress_tk.Rd
-0e3c94f6895b7218f7c0aa60be62a409 *man/progress_win.Rd
-13212fc5e1602a6a5f06e90cabe390bf *man/quickdf.Rd
-32590979c2f2c53d84dcc634b102c5e7 *man/quoted.Rd
-2a52a63c04e805bb604e8e68f95e01a0 *man/r_ply.Rd
-d07d0e83bbbe03417ae22ca158ce55d5 *man/raply.Rd
-d7811882a3cb607dd5ff4fc71d81a39c *man/rbind.fill.Rd
-615864fe9a2917d474be097fd10e3c70 *man/rbind.fill.matrix.Rd
-b16dd4428fe00cd8c7af4f9368570fca *man/rdply.Rd
-15caff5bb35366d7161fb8ddd00328d7 *man/reduce_dim.Rd
-4925909bd5e4e4fa668da77200865be2 *man/rename.Rd
-84ed21424b2528e4f4e75453ef045f66 *man/revalue.Rd
-ed68d9045b8faa3790fa42c6d96d264d *man/rlply.Rd
-3636bd0de16181a7b32d6fa38af00bd0 *man/round_any.Rd
-9c974ee3f4474ac74c9c9a60f662cb03 *man/splat.Rd
-8a1d5936fd6a63480f33890a26102ba7 *man/split_indices.Rd
-dcbea80602c0d5c9626b6ea2de228f94 *man/split_labels.Rd
-34f4376f16955b48a7e7bc463083efad *man/splitter_a.Rd
-4e5bb4f6cda668c8c823fbd1ad96a651 *man/splitter_d.Rd
-73169417e97bf94ab6fd2da68ffb6526 *man/strip_splits.Rd
-04da1fd0201904b43c42917089026113 *man/summarise.Rd
-698bab1ef9ddd92aa29af5f252e7e4ff *man/take.Rd
-f965825f4813cb5890c5afb6cc8d7690 *man/true.Rd
-29f454fa61e816d69cff2ba1993e699f *man/try_default.Rd
-dbafa9f424846e45f77e9d961b1ef717 *man/tryapply.Rd
-1268056f8d0e765ad0f99af317a906ab *man/unrowname.Rd
-2ea2af25c66ef2a745886cbd9b640353 *man/vaggregate.Rd
-021c0a6dbed105a81284fb031280df1d *src/loop-apply.c
-9e136c2fbd222ce76ba3d0bfa05d7e80 *src/split-numeric.c
+ac7563c48431d42b337653bc9470f0e4 *man/a_ply.Rd
+0717e4bc57b3b9c781c349efb86e342c *man/aaply.Rd
+162da28b198c3f54ada2c06ba1f10d69 *man/adply.Rd
+61fdfc2fe1e867af44fd2edb3962561a *man/alply.Rd
+c6737e21f849af791242abe7d42e3c6e *man/amv_dim.Rd
+13d927a2404446851b56c74b7c5a0974 *man/amv_dimnames.Rd
+a46d634fe4135663c2a413dbaa309891 *man/arrange.Rd
+ce3a67db1d183abb5d791fb738afa662 *man/as.data.frame.function.Rd
+31c8a413ffd907a4ae2295e78c5c41d6 *man/as.list.split.Rd
+125ea78966866bb20a3145f352db08ff *man/as.quoted.Rd
+a9d1dcc2e181e1e5dc18b55560c373aa *man/baseball.Rd
+242ded6412a6d8fb868eaa4b62dae66e *man/colwise.Rd
+d073a35a6fd27766de0c1531eda909e5 *man/compact.Rd
+525306f5b64d0a711fbc89ed736c9194 *man/count.Rd
+05e27d334ef04448d23b34ec46c60769 *man/create_progress_bar.Rd
+c044fbb3571927c57fe498d819f76511 *man/d_ply.Rd
+d4e70ed35830c41b168cf4f0b952c815 *man/daply.Rd
+2ecff2004fe134fcc39aa35db11b53db *man/ddply.Rd
+9a06d3f0de98bbf0dea7159b6896ad5b *man/defaults.Rd
+c357f0e4981cc26d10253b37d5341e71 *man/desc.Rd
+79e2db3915e958bfa14f5e8eaa68ad12 *man/dims.Rd
+1418940d42c92cf47a4ecf299f31b6e6 *man/dlply.Rd
+1d25347e06473cb692b295acd762a213 *man/each.Rd
+054cb91b58e9a156d54cdceb99481e64 *man/empty.Rd
+5ddc37a1a35ef3a3a3eabb5681aab318 *man/eval.quoted.Rd
+b41a502142050136638be5fb88e056af *man/failwith.Rd
+df3b19f0a74d194cde730c9bca65e60c *man/get-split.Rd
+e36b3ec1a2186e752541ba26ccd13fee *man/here.Rd
+86a68a1c3aa9dc9fd8dbb35eff5a66a9 *man/id.Rd
+abfd9fb1db10f420f2ef73b444c6042c *man/id_var.Rd
+af3d285c8cffdf1f1930d0c0b4415667 *man/idata.frame.Rd
+c4573fbd4cd99d964948ba464ae946cc *man/indexed_array.Rd
+db51b19ad409f316b4048714601ffcc1 *man/indexed_df.Rd
+c4c73b67ee9e610ecc639844e99c0c63 *man/is.discrete.Rd
+0ab4a96160495e032ff28400fb5cfe22 *man/is.formula.Rd
+529aec01f0fdd9485ad974dd6b270a1c *man/isplit2.Rd
+edf76d7b01d757b7ed39d793da6fb3f9 *man/join.Rd
+8e02a02baa6c4abe1385c5c8384050b0 *man/join.keys.Rd
+f4487b0ac86bd005958474da4f621394 *man/join_all.Rd
+ee498cd95cbbb9d65b3ae90cf12a3e22 *man/l_ply.Rd
+d29fcc3c1369b14433e11a7a1cc3959b *man/laply.Rd
+3aaccfa00175e832da3cdd966df12d47 *man/ldply.Rd
+b6bb7b54b4ebb9aa9d54088a1ce6dc9c *man/liply.Rd
+dc8df8de5662e83682985c5fe1b84c2a *man/list_to_array.Rd
+d59be82925f6d53f5a35fe13c913005c *man/list_to_dataframe.Rd
+6da3d504a10dfa340db784da70d781f9 *man/list_to_vector.Rd
+0f6dd3af5807166276eea60c3311bca0 *man/llply.Rd
+2125accf3842daf3d1fe69d3daa45bc4 *man/loop_apply.Rd
+4ae856a0adc3b7bcc47bba67857a3171 *man/m_ply.Rd
+7fa95148eb581bda7884b1f2c96cbc58 *man/maply.Rd
+f9d8e8f3e0c07a19390294a012b5300b *man/mapvalues.Rd
+899a76ec0843c1482c623b26608a8bc5 *man/match_df.Rd
+a9328642ff6e8ca3113a240eec9b76f9 *man/mdply.Rd
+ed8b97ad4129f1b962786dbd59a6a6ec *man/mlply.Rd
+70f471faa695d12a13e0fb5e22c137b8 *man/mutate.Rd
+61887e3a6fab5f8df3a1dd3aec0285de *man/name_rows.Rd
+4517633c15c758077114c4ca4e5c80d1 *man/names.quoted.Rd
+c0df5e2de7afaa49e55d40764db2453f *man/nunique.Rd
+26b781db290088be779a7b3057b46d71 *man/ozone.Rd
+02917b711f88ecec07d286cde41b4bb7 *man/plyr.Rd
+3e98d20eec084680efeaebebeb64477c *man/print.quoted.Rd
+689fe0eb1d86d55ada75d1be596878b6 *man/print.split.Rd
+dae967b4bd1abff5212b40685b7fb768 *man/progress_none.Rd
+2414c20ffabb82fc389dc2075440e50f *man/progress_text.Rd
+b83122c08f30caeb53fe83d45c1ddf06 *man/progress_time.Rd
+8895690a4ea7f92de532d76b7901817a *man/progress_tk.Rd
+c1fac41a81a3c2df51c1e043d223e51e *man/progress_win.Rd
+0cc3199131255ef70c39fc8c335c2eb3 *man/quickdf.Rd
+550ea88bdc7fd78f85a600f952560d03 *man/quoted.Rd
+6d888838f23da18e62235e6b024e5ad9 *man/r_ply.Rd
+3cf477584f98e23bc9a9a14ea9b6ac7d *man/raply.Rd
+171637879fb38861e5348021c4823d21 *man/rbind.fill.Rd
+afe1b642d9c6f39473b1711bf77c495f *man/rbind.fill.matrix.Rd
+6cd90c8e671d57b57299f3aa410a0722 *man/rdply.Rd
+e0b80e565d5134929fac7850ae96fb4d *man/reduce_dim.Rd
+304b67a185ac1fd5631257213074b670 *man/rename.Rd
+b2c9a28954ffb99e8a9e94b7080a93f4 *man/revalue.Rd
+3debf6b1458a5d500d723b3be7c767e4 *man/rlply.Rd
+20f64ebb7814160578db5e65215f3db1 *man/round_any.Rd
+c163527e49af38ad819b15b6a81bac99 *man/splat.Rd
+3131f9dbe17149ff748b0c092ebcc320 *man/split_indices.Rd
+b3978778315673d43609039dcaa72d40 *man/split_labels.Rd
+4c39a6c3c65a68db084edfc126959fd1 *man/splitter_a.Rd
+22ff3206e9eee2af27b00a159d838d78 *man/splitter_d.Rd
+3da1da32ffbeb8db8e5cd9ecf584f5ce *man/strip_splits.Rd
+22702c6c29248dbf8dd40d88a49e8760 *man/summarise.Rd
+8dee654011082c3e4464efbc073d75bf *man/take.Rd
+d4eb68c7800a13044ecb821c26b603c7 *man/true.Rd
+1b8e50014ced0033e54fd1862c43d7c6 *man/try_default.Rd
+eb778877be830e480848287bd1ca6cd0 *man/tryapply.Rd
+f763623701b5a5b6de951bfcd330ddf9 *man/unrowname.Rd
+31338896c22a50295e87ecf087b92eb4 *man/vaggregate.Rd
+20e536a9ddb6ea12440c2d75ae780030 *src/RcppExports.cpp
+3863469b0ab2be2e828f7c4e7a0d8f40 *src/loop-apply.cpp
+a32b01aabc1e476e7aafec401b89e6f4 *src/split-numeric.cpp
 a16ff31afc22b8d7893bfcb504d98355 *tests/test-all.R
diff --git a/NAMESPACE b/NAMESPACE
index b77d47e..ad92b2a 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -1,3 +1,5 @@
+# Generated by roxygen2 (4.0.0): do not edit by hand
+
 S3method("[",idf)
 S3method("[",indexed)
 S3method("[",quoted)
@@ -23,6 +25,7 @@ S3method(length,indexed)
 S3method(length,indexed_array)
 S3method(names,idf)
 S3method(names,indexed)
+S3method(names,indexed_array)
 S3method(names,quoted)
 S3method(print,indexed)
 S3method(print,quoted)
@@ -103,5 +106,6 @@ export(try_default)
 export(tryapply)
 export(unrowname)
 export(vaggregate)
+importFrom(Rcpp,sourceCpp)
 importFrom(stats,setNames)
 useDynLib(plyr)
diff --git a/NEWS b/NEWS
index e8bdb85..743e746 100644
--- a/NEWS
+++ b/NEWS
@@ -1,420 +1,459 @@
-Version 1.8
-------------------------------------------------------------------------------
-
-NEW FEATURES AND FUNCTIONS
-
-* `**ply` gain a `.inform` argument (previously only available in `llply`) - this gives more useful debugging information at the cost of some speed. (Thanks to Brian Diggs, #57)
-
-* if `.dims = TRUE` `alply`'s output gains dimensions and dimnames, similar to `apply`. Sequential indexing of a list produced by `alply` should be unaffected. (Peter Meilstrup)
-
-* `colwise`, `numcolwise` and `catcolwise` now all accept additional arguments in .... (Thanks to Stavros Macrakis, #62)
-
-* `here` makes it possible to use `**ply` + a function that uses non-standard evaluation (e.g. `summarise`, `mutate`, `subset`, `arrange`) inside a function.  (Thanks to Peter Meilstrup, #3)
-
-* `join_all` recursively joins a list of data frames. (Fixes #29)
-
-* `name_rows` provides a convenient way of saving and then restoring row names so that you can preserve them if you need to. (#61)
-
-* `progress_time` (used with `.progress = "time"`) estimates the amount of time remaining before the job is completed. (Thanks to Mike Lawrence, #78)
-
-* `summarise` now works iteratively so that later columns can refer to earlier.  (Thanks to Jim Hester, #44)
-
-* `take` makes it easy to subset along an arbitrary dimension.
-
-* Improved documentation thanks to patches from Tim Bates.
-
-PARALLEL PLYR
-
-* `**ply` gains a `.paropts` argument, a list of options that is passed onto `foreach` for controlling parallel computation.
-
-* `*_ply` now accepts `.parallel` argument to enable parallel processing. (Fixes #60)
-
-* Progress bars are disabled when using parallel plyr (Fixes #32)
-
-PERFORMANCE IMPROVEMENTS
-
-* `a*ply`: 25x speedup when indexing array objects, 3x speedup when indexing data frames.  This should substantially reduce the overhead of using `a*ply`
-
-* `d*ply` subsetting has been considerably optimised: this will have a small impact unless you have a very large number of groups, in which case it will be considerably faster.
-
-* `idata.frame`: Subsetting immutable data frames with `[.idf` is now
-  faster (Peter Meilstrup)
-
-* `quickdf` is around 20% faster
-
-* `split_indices`, which powers much internal splitting code (like `vaggregate`, `join` and `d*ply`) is about 2x faster.  It was already incredible fast ~0.2s for 1,000,000 obs, so this won't have much impact on overall performance
-
-BUG FIXES
-
-* `*aply` functions now bind list mode results into a list-array (Peter Meilstrup)
-
-* `*aply` now accepts 0-dimension arrays as inputs. (#88)
-
-* `*dply` now deals better with matrix results, converting them to data frames, rather than vectors. (Fixes #12)
-
-* `d*ply` will now preserve factor levels input if `drop = FALSE` (#81)
-
-* `join` works correctly when there are no common rows (Fixes #74), or when one input has no rows (Fixes #48). It also consistently orders the columns: common columns, then x cols, then y cols (Fixes #40).
-
-* `quickdf` correctly handles NA variable names. (Fixes #66. Thanks to Scott Kostyshak)
-
-* `rbind.fill` and `rbind.fill.matrix` work consistently with matrices and data frames with zero rows. Fixes #79. (Peter Meilstrup)
-
-* `rbind.fill` now stops if inputs are not data frames. (Fixes #51)
-
-* `rbind.fill` now works consistently with 0 column data frames
-
-* `round_any` now works with `POSIXct` objects, thanks to Jean-Olivier Irisson (#76)
-
-Version 1.7.1
-------------------------------------------------------------------------------
-
-* Fix bug in id, using numeric instead of integer
-
-Version 1.7
-------------------------------------------------------------------------------
-
-* `rbind.fill`: if a column contains both factors and characters (in different
-  inputs), the resulting column will be coerced to character
-
-* When there are more than 2^31 distinct combinations `id`, switches to a
-  slower fallback strategy using strings (inspired by `merge`) that guarantees
-  correct results. This fixes problems with `join` when joining across many
-  columns. (Fixes #63)
-
-* `split_indices` checks input more aggressively to prevent segfaults. 
-   Fixes #43.
-
-* fix small bug in `loop_apply` which lead to segfaults in certain
-  circumstances. (Thanks to Pål Westermark for patch)
-
-* `itertools` and `iterators` moved to suggests from imports so that plyr now
-  only depends on base R.
-
-Version 1.6
-------------------------------------------------------------------------------
-
-* documentation improved using new features of `roxygen2`
-
-* fixed namespacing issue which lead to lost labels when subsetting the
-  results of `*lply`
-
-* `colwise` automatically strips off split variables.
-
-* `rlply` now correctly deals with `rlply(4, NULL)` (thanks to bug report from
-  Eric Goldlust)
-
-* `rbind.fill` tries harder to keep attributes, retaining the attributes from
-  the first occurrence of each column it finds. It also now works with
-  variables of class `POSIXlt` and preserves the ordered status of factors.
-
-* `arrange` now works with one column data frames
-
-Version 1.5.2
-------------------------------------------------------------------------------
-
-* `d*ply` returns correct number of rows when function returns vector
-
-* fix NAMESPACE bug which was causing problems with ggplot2
-
-Version 1.5.1
-------------------------------------------------------------------------------
-
-* `rbind.fill` now treats 1d arrays in the same way as `rbind` (i.e. it turns
-  them into ordinary vectors)
-
-* fix bug in rename when renaming multiple columns
-
-Version 1.5 (2011-03-02)
-------------------------------------------------------------------------------
-
-NEW FEATURES
-
-* new `strip_splits` function removes splitting variables from the data frames
-  returned by `ddply`.
-
-* `rename` moved in from reshape, and rewritten.
-
-* new `match_df` function makes it easy to subset a data frame to only contain
-  values matching another data frame. Inspired by
-  http://stackoverflow.com/questions/4693849.
-
-BUG FIXES
-
-* `**ply` now works when passed a list of functions
-
-* `*dply` now correctly names output even when some output combinations are
-  missing (NULL) (Thanks to bug report from Karl Ove Hufthammer)
-
-* `*dply` preserves the class of many more object types.
-
-* `a*ply` now correctly works with zero length margins, operating on the
-  entire object (Thanks to bug report from Stavros Macrakis)
-
-* `join` now implements joins in a more SQL like way, returning all possible
-  matches, not just the first one. It is still a (little) faster than merge.
-  The previous behaviour is accessible with `match = "first"`.
-
-* `join` is now more symmetric so that `join(x, y, "left")` is closer to
-  `join(y, x, "right")`, modulo column ordering
-
-* `named.quoted` failed when quoted expressions were longer than 50
-  characters. (Thanks to bug report from Eric Goldlust)
-
-* `rbind.fill` now correctly maintains POSIXct tzone attributes and preserves
-  missing factor levels
-
-* `split_labels` correctly preserves empty factor levels, which means that
-  `drop = FALSE` should work in more places. Use `base::droplevels` to remove
-  levels that don't occur in the data, and `drop = T` to remove combinations
-  of levels that don't occur.
-
-* `vaggregate` now passes `...` to the aggregation function when working out
-  the output type (thanks to bug report by Pavan Racherla)
-
-Version 1.4.1 (2011-04-05)
-------------------------------------------------------------------------------
-
-* Add citation to JSS article
-
-Version 1.4 (2011-01-03)
-------------------------------------------------------------------------------
-
-* `count` now takes an additional parameter `wt_var` which allows you to
-  compute weighted sums. This is as fast, or faster than, `tapply` or `xtabs`.
-
-* Really fix bug in `names.quoted`
-
-* `.` now captures the environment in which it was evaluated. This should fix
-  an esoteric class of bugs which no-one probably ever encountered, but will
-  form the basis for an improved version of `ggplot2::aes`.
-
-Version 1.3.1 (2010-12-30)
-------------------------------------------------------------------------------
-
-* Fix bug in `names.quoted` that interfered with ggplot2
-
-Version 1.3 (2010-12-28)
-------------------------------------------------------------------------------
-
-NEW FEATURES
-
-* new function `mutate` that works like transform to add new columns or
-  overwrite existing columns, but computes new columns iteratively so later
-  transformations can use columns created by earlier transformations. (It's
-  also about 10x faster) (Fixes #21)
-
-BUG FIXES
-
-* split column names are no longer coerced to valid R names.
-
-* `quickdf` now adds names if missing
-
-* `summarise` preserves variable names if explicit names not provided (Fixes
-  #17)
-
-* `arrays` with names should be sorted correctly once again (also fixed a bug
-  in the test case that prevented me from catching this automatically)
-
-* `m_ply` no longer possesses .parallel argument (mistakenly added)
-
-* `ldply` (and hence `adply` and `ddply`) now correctly passes on .parallel
-  argument (Fixes #16)
-
-* `id` uses a better strategy for converting to integers, making it possible
-  to use for cases with larger potential numbers of combinations
-
-Version 1.2.1 (2010-09-10)
-------------------------------------------------------------------------------
-
-* Fix bug in llply fast path that causes problems with ggplot2.
-
-Version 1.2 (2010-09-09)
-------------------------------------------------------------------------------
-
-NEW FEATURES
-
-* l*ply, d*ply, a*ply and m*ply all gain a .parallel argument that when TRUE,
-  applies functions in parallel using a parallel backend registered with the
-  foreach package:
-
-  x <- seq_len(20)
-  wait <- function(i) Sys.sleep(0.1)
-  system.time(llply(x, wait))
-  #  user  system elapsed 
-  # 0.007   0.005   2.005 
-   
-  library(doMC)
-  registerDoMC(2) 
-  system.time(llply(x, wait, .parallel = TRUE))
-  #  user  system elapsed 
-  # 0.020   0.011   1.038 
-
-  This work has been generously supported by BD (Becton Dickinson).
-
-MINOR CHANGES
-
-* a*ply and m*ply gain an .expand argument that controls whether data frames
-  produce a single output dimension (one element for each row), or an output
-  dimension for each variable.
-
-* new vaggregate (vector aggregate) function, which is equivalent to tapply,
-  but much faster (~ 10x), since it avoids copying the data.
-
-* llply: for simple lists and vectors, with no progress bar, no extra info,
-  and no parallelisation, llply calls lapply directly to avoid all the
-  overhead associated with those unused extra features.
-
-* llply: in serial case, for loop replaced with custom C function that takes
-  about 40% less time (or about 20% less time than lapply). Note that as a
-  whole, llply still has much more overhead than lapply.
-
-* round_any now lives in plyr instead of reshape
-
-BUG FIXES
-
-* list_to_array works correct even when there are missing values in the array.  
-  This is particularly important for daply.
-
-Version 1.1 (2010-07-19)
-------------------------------------------------------------------------------
-
-* *dply deals more gracefully with the case when all results are NULL 
-  (fixes #10)
-
-* *aply correctly orders output regardless of dimension names 
-  (fixes #11)
-
-* join gains type = "full" which preserves all x and y rows
-
-Version 1.0 (2010-07-02)
-------------------------------------------------------------------------------
-
-New functions:
-
-* arrange, a new helper method for reordering a data frame.
-* count, a version of table that returns data frames immediately and that is
-  much much faster for high-dimensional data.
-* desc makes it easy to sort any vector in descending order
-* join, works like merge but can be much faster and has a somewhat simpler
-  syntax drawing from SQL terminology
-* rbind.fill.matrix is like rbind.fill but works for matrices, code 
-  contributed by C. Beleites
-
-Speed improvements
-
-* experimental immutable data frame (idata.frame) that vastly speeds up
-  subsetting - for large datasets with large numbers of groups, this can yield
-  10-fold speed ups. See examples in ?idata.frame to see how to use it.
-* rbind.fill rewritten again to increase speed and work with more data types
-* d*ply now much faster with nested groups
-
-  This work has been generously supported by BD (Becton Dickinson).
-  
-
-New features:
-
-* d*ply now accepts NULL for splitting variables, indicating that the data
-  should not be split
-* plyr no longer exports internal functions, many of which were causing
-  clashes with other packages
-* rbind.fill now works with data frame columns that are lists or matrices
-* test suite ensures that plyr behaviour is correct and will remain correct
-  as I make future improvements.
-
-Bug fixes:
-
-* **ply: if zero splits, empty list(), data.frame() or logical() returned, 
-  as appropriate for the output type
-* **ply: leaving .fun as NULL now always returns list 
-  (thanks to Stavros Macrakis for the bug report)
-* a*ply: labels now respect options(stringAsFactors)
-* each: scoping bug fixed, thanks to Yasuhisa Yoshida for the bug report
-* list_to_dataframe is more consistent when processing a single data frame
-* NAs preserved in more places
-* progress bars: guaranteed to terminate even if **ply prematurely terminates
-* progress bars: misspelling gives informative warning, instead of
-  uninformative error
-* splitter_d: fixed ordering bug when .drop = FALSE
-
-Version 0.1.9 (2009-06-23)
-------------------------------------------------------------------------------
-
-
-* fix bug in rbind.fill when NULLs present in list
-* improve each to recognise when all elements are numeric
-* fix labelling bug in d*ply when .drop = FALSE
-* additional methods for quoted objects
-* add summarise helper - this function is like transform, but creates a new data frame rather than reusing the old (thanks to Brendan O'Connor for the neat idea)
-
-Version 0.1.8 (2009-04-20)
-------------------------------------------------------------------------------
-
-
-* made rbind a little faster (~20%) using an idea from Richard Raubertas
-* daply now works correctly when splitting variables that contain empty factor levels
-
-Version 0.1.7 (2009-04-15)
-------------------------------------------------------------------------------
-
- * Version that rbind.fill copies attributes.
-
-Version 0.1.6 (2009-04-15)
-------------------------------------------------------------------------------
-
-
-Improvements:
-
-* all ply functions deal more elegantly when given function names: can supply a vector of function names, and name is used as label in output
-* failwith and each now work with function names as well as functions (i.e. "nrow" instead of nrow)
-* each now accepts a list of functions or a vector of function names
-* l*ply will use list names where present
-* if .inform is TRUE, error messages will give you information about where errors within your data - hopefully this will make problems easier to track down
-* d*ply no longer converts splitting variables to factors when drop = T (thanks to bug report from Charlotte Wickham)
-
-Speed-ups
-
-* massive speed ups for splitting large arrays
-* fixed typo that was causing a 50% speed penalty for d*ply
-* rewritten rbind.fill is considerably (> 4x) faster for many data frames
-* colwise about twice as fast
-
-Bug fixes:
-
-* daply: now works when the data frame is split by multiple variables
-* aaply: now works with vectors
-* ddply: first variable now varies slowest as you'd expect
-
-
-Version 0.1.5 (2009-02-23)
-------------------------------------------------------------------------------
-
-* colwise now accepts a quoted list as its second argument.  This allows you to specify the names of columns to work on: colwise(mean, .(lat, long))
-* d_ply and a_ply now correctly pass ... to the function
-
-Version 0.1.4 (2008-12-12)
-------------------------------------------------------------------------------
-
- * Greatly improved speed (> 10x faster) and memory usage (50%) for splitting data frames with many combinations
- * Splitting variables containing missing values now handled consistently
-
-Version 0.1.3 (2008-11-19)
-------------------------------------------------------------------------------
-
-* Fixed problem where when splitting by a variable that contained missing values, missing combinations would be drop, and labels wouldn't match up
-
-Version 0.1.2 (2008-11-18)
-------------------------------------------------------------------------------
-
-  * a*ply now works correctly with array-lists
-  * drop. -> .drop
-  * r*ply now works with ...
-  * use inherits instead of is so method package doesn't need to be loaded
-  * fix bug with using formulas
-
-Version 0.1.1 (2008-10-08)
-------------------------------------------------------------------------------
-
-  * argument names now start with . (instead of ending with it) - this should prevent name clashes with arguments of the called function 
-  * return informative error if .fun is not a function
-  * use full names in all internal calls to avoid argument name clashes
\ No newline at end of file
+Version 1.8.1
+------------------------------------------------------------------------------
+
+* New parameter `.id` to `ldply()` and `rdply()` that specifies the name of
+  the index column. (Thanks to Kirill Müller, #107, #140, #142)
+
+* New parameter `.id` to `rdply()` that specifies the name of the index
+  column. (Thanks to Kirill Müller, #142)
+
+* The `.id` column in `ldply()` is generated as a factor to preserve the sort
+  order. (Thanks to Kirill Müller, #137)
+
+* `rbind.fill` now silently drops NULL inputs (#138)
+
+* `rbind.fill` avoids array copying which had produced quadratic time
+  complexity. `*dply` of large numbers of groups should be faster.
+  (Contributed by Peter Meilstrup)
+
+* `rbind.fill` handles non-numeric matrix columns (i.e. factor arrays,
+  character arrays, list arrays); also arrays with more than 2
+  dimensions can be used. Dimnames of array columns are now preserved.
+  (Contributed by Peter Meilstrup)
+
+* `rbind.fill(x,y)` converts factor columns of Y to character when
+  columns of X are character. `join(x,y)` and `match_df(x,y)` now work
+  when the key column in X is character and Y is factor. (Contributed
+  by Peter Meilstrup)
+
+* Fix faulty array allocation which caused problems when using `split_indices`
+  with large (> 2^24) vectors.  (Fixes #131)
+
+* `list_to_array()` incorrectly determined dimensions if column of labels
+  contained any missing values (#169).
+
+* `r*ply` expression is evaluated exactly `.n` times, evaluation results are
+  consistent with side effects. (#158, thanks to Kirill Müller)
+
+Version 1.8
+------------------------------------------------------------------------------
+
+NEW FEATURES AND FUNCTIONS
+
+* `**ply` gain a `.inform` argument (previously only available in `llply`) - this gives more useful debugging information at the cost of some speed. (Thanks to Brian Diggs, #57)
+
+* if `.dims = TRUE` `alply`'s output gains dimensions and dimnames, similar to `apply`. Sequential indexing of a list produced by `alply` should be unaffected. (Peter Meilstrup)
+
+* `colwise`, `numcolwise` and `catcolwise` now all accept additional arguments in .... (Thanks to Stavros Macrakis, #62)
+
+* `here` makes it possible to use `**ply` + a function that uses non-standard evaluation (e.g. `summarise`, `mutate`, `subset`, `arrange`) inside a function.  (Thanks to Peter Meilstrup, #3)
+
+* `join_all` recursively joins a list of data frames. (Fixes #29)
+
+* `name_rows` provides a convenient way of saving and then restoring row names so that you can preserve them if you need to. (#61)
+
+* `progress_time` (used with `.progress = "time"`) estimates the amount of time remaining before the job is completed. (Thanks to Mike Lawrence, #78)
+
+* `summarise` now works iteratively so that later columns can refer to earlier.  (Thanks to Jim Hester, #44)
+
+* `take` makes it easy to subset along an arbitrary dimension.
+
+* Improved documentation thanks to patches from Tim Bates.
+
+PARALLEL PLYR
+
+* `**ply` gains a `.paropts` argument, a list of options that is passed onto `foreach` for controlling parallel computation.
+
+* `*_ply` now accepts `.parallel` argument to enable parallel processing. (Fixes #60)
+
+* Progress bars are disabled when using parallel plyr (Fixes #32)
+
+PERFORMANCE IMPROVEMENTS
+
+* `a*ply`: 25x speedup when indexing array objects, 3x speedup when indexing data frames.  This should substantially reduce the overhead of using `a*ply`
+
+* `d*ply` subsetting has been considerably optimised: this will have a small impact unless you have a very large number of groups, in which case it will be considerably faster.
+
+* `idata.frame`: Subsetting immutable data frames with `[.idf` is now
+  faster (Peter Meilstrup)
+
+* `quickdf` is around 20% faster
+
+* `split_indices`, which powers much internal splitting code (like `vaggregate`, `join` and `d*ply`) is about 2x faster.  It was already incredible fast ~0.2s for 1,000,000 obs, so this won't have much impact on overall performance
+
+BUG FIXES
+
+* `*aply` functions now bind list mode results into a list-array (Peter Meilstrup)
+
+* `*aply` now accepts 0-dimension arrays as inputs. (#88)
+
+* `count` now works correctly for factor and Date inputs. (Fixes #130)
+
+* `*dply` now deals better with matrix results, converting them to data frames, rather than vectors. (Fixes #12)
+
+* `d*ply` will now preserve factor levels input if `drop = FALSE` (#81)
+
+* `join` works correctly when there are no common rows (Fixes #74), or when one input has no rows (Fixes #48). It also consistently orders the columns: common columns, then x cols, then y cols (Fixes #40).
+
+* `quickdf` correctly handles NA variable names. (Fixes #66. Thanks to Scott Kostyshak)
+
+* `rbind.fill` and `rbind.fill.matrix` work consistently with matrices and data frames with zero rows. Fixes #79. (Peter Meilstrup)
+
+* `rbind.fill` now stops if inputs are not data frames. (Fixes #51)
+
+* `rbind.fill` now works consistently with 0 column data frames
+
+* `round_any` now works with `POSIXct` objects, thanks to Jean-Olivier Irisson (#76)
+
+Version 1.7.1
+------------------------------------------------------------------------------
+
+* Fix bug in id, using numeric instead of integer
+
+Version 1.7
+------------------------------------------------------------------------------
+
+* `rbind.fill`: if a column contains both factors and characters (in different
+  inputs), the resulting column will be coerced to character
+
+* When there are more than 2^31 distinct combinations `id`, switches to a
+  slower fallback strategy using strings (inspired by `merge`) that guarantees
+  correct results. This fixes problems with `join` when joining across many
+  columns. (Fixes #63)
+
+* `split_indices` checks input more aggressively to prevent segfaults.
+   Fixes #43.
+
+* fix small bug in `loop_apply` which lead to segfaults in certain
+  circumstances. (Thanks to Pål Westermark for patch)
+
+* `itertools` and `iterators` moved to suggests from imports so that plyr now
+  only depends on base R.
+
+Version 1.6
+------------------------------------------------------------------------------
+
+* documentation improved using new features of `roxygen2`
+
+* fixed namespacing issue which lead to lost labels when subsetting the
+  results of `*lply`
+
+* `colwise` automatically strips off split variables.
+
+* `rlply` now correctly deals with `rlply(4, NULL)` (thanks to bug report from
+  Eric Goldlust)
+
+* `rbind.fill` tries harder to keep attributes, retaining the attributes from
+  the first occurrence of each column it finds. It also now works with
+  variables of class `POSIXlt` and preserves the ordered status of factors.
+
+* `arrange` now works with one column data frames
+
+Version 1.5.2
+------------------------------------------------------------------------------
+
+* `d*ply` returns correct number of rows when function returns vector
+
+* fix NAMESPACE bug which was causing problems with ggplot2
+
+Version 1.5.1
+------------------------------------------------------------------------------
+
+* `rbind.fill` now treats 1d arrays in the same way as `rbind` (i.e. it turns
+  them into ordinary vectors)
+
+* fix bug in rename when renaming multiple columns
+
+Version 1.5 (2011-03-02)
+------------------------------------------------------------------------------
+
+NEW FEATURES
+
+* new `strip_splits` function removes splitting variables from the data frames
+  returned by `ddply`.
+
+* `rename` moved in from reshape, and rewritten.
+
+* new `match_df` function makes it easy to subset a data frame to only contain
+  values matching another data frame. Inspired by
+  http://stackoverflow.com/questions/4693849.
+
+BUG FIXES
+
+* `**ply` now works when passed a list of functions
+
+* `*dply` now correctly names output even when some output combinations are
+  missing (NULL) (Thanks to bug report from Karl Ove Hufthammer)
+
+* `*dply` preserves the class of many more object types.
+
+* `a*ply` now correctly works with zero length margins, operating on the
+  entire object (Thanks to bug report from Stavros Macrakis)
+
+* `join` now implements joins in a more SQL like way, returning all possible
+  matches, not just the first one. It is still a (little) faster than merge.
+  The previous behaviour is accessible with `match = "first"`.
+
+* `join` is now more symmetric so that `join(x, y, "left")` is closer to
+  `join(y, x, "right")`, modulo column ordering
+
+* `named.quoted` failed when quoted expressions were longer than 50
+  characters. (Thanks to bug report from Eric Goldlust)
+
+* `rbind.fill` now correctly maintains POSIXct tzone attributes and preserves
+  missing factor levels
+
+* `split_labels` correctly preserves empty factor levels, which means that
+  `drop = FALSE` should work in more places. Use `base::droplevels` to remove
+  levels that don't occur in the data, and `drop = T` to remove combinations
+  of levels that don't occur.
+
+* `vaggregate` now passes `...` to the aggregation function when working out
+  the output type (thanks to bug report by Pavan Racherla)
+
+Version 1.4.1 (2011-04-05)
+------------------------------------------------------------------------------
+
+* Add citation to JSS article
+
+Version 1.4 (2011-01-03)
+------------------------------------------------------------------------------
+
+* `count` now takes an additional parameter `wt_var` which allows you to
+  compute weighted sums. This is as fast, or faster than, `tapply` or `xtabs`.
+
+* Really fix bug in `names.quoted`
+
+* `.` now captures the environment in which it was evaluated. This should fix
+  an esoteric class of bugs which no-one probably ever encountered, but will
+  form the basis for an improved version of `ggplot2::aes`.
+
+Version 1.3.1 (2010-12-30)
+------------------------------------------------------------------------------
+
+* Fix bug in `names.quoted` that interfered with ggplot2
+
+Version 1.3 (2010-12-28)
+------------------------------------------------------------------------------
+
+NEW FEATURES
+
+* new function `mutate` that works like transform to add new columns or
+  overwrite existing columns, but computes new columns iteratively so later
+  transformations can use columns created by earlier transformations. (It's
+  also about 10x faster) (Fixes #21)
+
+BUG FIXES
+
+* split column names are no longer coerced to valid R names.
+
+* `quickdf` now adds names if missing
+
+* `summarise` preserves variable names if explicit names not provided (Fixes
+  #17)
+
+* `arrays` with names should be sorted correctly once again (also fixed a bug
+  in the test case that prevented me from catching this automatically)
+
+* `m_ply` no longer possesses .parallel argument (mistakenly added)
+
+* `ldply` (and hence `adply` and `ddply`) now correctly passes on .parallel
+  argument (Fixes #16)
+
+* `id` uses a better strategy for converting to integers, making it possible
+  to use for cases with larger potential numbers of combinations
+
+Version 1.2.1 (2010-09-10)
+------------------------------------------------------------------------------
+
+* Fix bug in llply fast path that causes problems with ggplot2.
+
+Version 1.2 (2010-09-09)
+------------------------------------------------------------------------------
+
+NEW FEATURES
+
+* l*ply, d*ply, a*ply and m*ply all gain a .parallel argument that when TRUE,
+  applies functions in parallel using a parallel backend registered with the
+  foreach package:
+
+  x <- seq_len(20)
+  wait <- function(i) Sys.sleep(0.1)
+  system.time(llply(x, wait))
+  #  user  system elapsed
+  # 0.007   0.005   2.005
+
+  library(doMC)
+  registerDoMC(2)
+  system.time(llply(x, wait, .parallel = TRUE))
+  #  user  system elapsed
+  # 0.020   0.011   1.038
+
+  This work has been generously supported by BD (Becton Dickinson).
+
+MINOR CHANGES
+
+* a*ply and m*ply gain an .expand argument that controls whether data frames
+  produce a single output dimension (one element for each row), or an output
+  dimension for each variable.
+
+* new vaggregate (vector aggregate) function, which is equivalent to tapply,
+  but much faster (~ 10x), since it avoids copying the data.
+
+* llply: for simple lists and vectors, with no progress bar, no extra info,
+  and no parallelisation, llply calls lapply directly to avoid all the
+  overhead associated with those unused extra features.
+
+* llply: in serial case, for loop replaced with custom C function that takes
+  about 40% less time (or about 20% less time than lapply). Note that as a
+  whole, llply still has much more overhead than lapply.
+
+* round_any now lives in plyr instead of reshape
+
+BUG FIXES
+
+* list_to_array works correct even when there are missing values in the array.
+  This is particularly important for daply.
+
+Version 1.1 (2010-07-19)
+------------------------------------------------------------------------------
+
+* *dply deals more gracefully with the case when all results are NULL
+  (fixes #10)
+
+* *aply correctly orders output regardless of dimension names
+  (fixes #11)
+
+* join gains type = "full" which preserves all x and y rows
+
+Version 1.0 (2010-07-02)
+------------------------------------------------------------------------------
+
+New functions:
+
+* arrange, a new helper method for reordering a data frame.
+* count, a version of table that returns data frames immediately and that is
+  much much faster for high-dimensional data.
+* desc makes it easy to sort any vector in descending order
+* join, works like merge but can be much faster and has a somewhat simpler
+  syntax drawing from SQL terminology
+* rbind.fill.matrix is like rbind.fill but works for matrices, code
+  contributed by C. Beleites
+
+Speed improvements
+
+* experimental immutable data frame (idata.frame) that vastly speeds up
+  subsetting - for large datasets with large numbers of groups, this can yield
+  10-fold speed ups. See examples in ?idata.frame to see how to use it.
+* rbind.fill rewritten again to increase speed and work with more data types
+* d*ply now much faster with nested groups
+
+  This work has been generously supported by BD (Becton Dickinson).
+
+
+New features:
+
+* d*ply now accepts NULL for splitting variables, indicating that the data
+  should not be split
+* plyr no longer exports internal functions, many of which were causing
+  clashes with other packages
+* rbind.fill now works with data frame columns that are lists or matrices
+* test suite ensures that plyr behaviour is correct and will remain correct
+  as I make future improvements.
+
+Bug fixes:
+
+* **ply: if zero splits, empty list(), data.frame() or logical() returned,
+  as appropriate for the output type
+* **ply: leaving .fun as NULL now always returns list
+  (thanks to Stavros Macrakis for the bug report)
+* a*ply: labels now respect options(stringAsFactors)
+* each: scoping bug fixed, thanks to Yasuhisa Yoshida for the bug report
+* list_to_dataframe is more consistent when processing a single data frame
+* NAs preserved in more places
+* progress bars: guaranteed to terminate even if **ply prematurely terminates
+* progress bars: misspelling gives informative warning, instead of
+  uninformative error
+* splitter_d: fixed ordering bug when .drop = FALSE
+
+Version 0.1.9 (2009-06-23)
+------------------------------------------------------------------------------
+
+
+* fix bug in rbind.fill when NULLs present in list
+* improve each to recognise when all elements are numeric
+* fix labelling bug in d*ply when .drop = FALSE
+* additional methods for quoted objects
+* add summarise helper - this function is like transform, but creates a new data frame rather than reusing the old (thanks to Brendan O'Connor for the neat idea)
+
+Version 0.1.8 (2009-04-20)
+------------------------------------------------------------------------------
+
+
+* made rbind a little faster (~20%) using an idea from Richard Raubertas
+* daply now works correctly when splitting variables that contain empty factor levels
+
+Version 0.1.7 (2009-04-15)
+------------------------------------------------------------------------------
+
+ * Version that rbind.fill copies attributes.
+
+Version 0.1.6 (2009-04-15)
+------------------------------------------------------------------------------
+
+
+Improvements:
+
+* all ply functions deal more elegantly when given function names: can supply a vector of function names, and name is used as label in output
+* failwith and each now work with function names as well as functions (i.e. "nrow" instead of nrow)
+* each now accepts a list of functions or a vector of function names
+* l*ply will use list names where present
+* if .inform is TRUE, error messages will give you information about where errors within your data - hopefully this will make problems easier to track down
+* d*ply no longer converts splitting variables to factors when drop = T (thanks to bug report from Charlotte Wickham)
+
+Speed-ups
+
+* massive speed ups for splitting large arrays
+* fixed typo that was causing a 50% speed penalty for d*ply
+* rewritten rbind.fill is considerably (> 4x) faster for many data frames
+* colwise about twice as fast
+
+Bug fixes:
+
+* daply: now works when the data frame is split by multiple variables
+* aaply: now works with vectors
+* ddply: first variable now varies slowest as you'd expect
+
+
+Version 0.1.5 (2009-02-23)
+------------------------------------------------------------------------------
+
+* colwise now accepts a quoted list as its second argument.  This allows you to specify the names of columns to work on: colwise(mean, .(lat, long))
+* d_ply and a_ply now correctly pass ... to the function
+
+Version 0.1.4 (2008-12-12)
+------------------------------------------------------------------------------
+
+ * Greatly improved speed (> 10x faster) and memory usage (50%) for splitting data frames with many combinations
+ * Splitting variables containing missing values now handled consistently
+
+Version 0.1.3 (2008-11-19)
+------------------------------------------------------------------------------
+
+* Fixed problem where when splitting by a variable that contained missing values, missing combinations would be drop, and labels wouldn't match up
+
+Version 0.1.2 (2008-11-18)
+------------------------------------------------------------------------------
+
+  * a*ply now works correctly with array-lists
+  * drop. -> .drop
+  * r*ply now works with ...
+  * use inherits instead of is so method package doesn't need to be loaded
+  * fix bug with using formulas
+
+Version 0.1.1 (2008-10-08)
+------------------------------------------------------------------------------
+
+  * argument names now start with . (instead of ending with it) - this should prevent name clashes with arguments of the called function
+  * return informative error if .fun is not a function
+  * use full names in all internal calls to avoid argument name clashes
diff --git a/R/RcppExports.R b/R/RcppExports.R
new file mode 100644
index 0000000..06d58d7
--- /dev/null
+++ b/R/RcppExports.R
@@ -0,0 +1,35 @@
+# This file was generated by Rcpp::compileAttributes
+# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
+
+#' Loop apply
+#'
+#' An optimised version of lapply for the special case of operating on
+#' \code{seq_len(n)}
+#'
+#' @param n length of sequence
+#' @param f function to apply to each integer
+#' @param env environment in which to evaluate function
+#' @useDynLib plyr
+#' @keywords internal manip
+loop_apply <- function(n, f) {
+    .Call('plyr_loop_apply', PACKAGE = 'plyr', n, f)
+}
+
+#' Split indices.
+#'
+#' An optimised version of split for the special case of splitting row
+#' indices into groups, as used by \code{\link{splitter_d}}
+#'
+#' @param index integer indices
+#' @param n largest integer (may not appear in index). This is hint: if 
+#'   the largest value of \code{group} is bigger than \code{n}, the output
+#'   will silently expand.
+#' @useDynLib plyr
+#' @keywords internal manip
+#' @export
+#' @examples
+#' split_indices(sample(10, 100, rep = TRUE), 10)
+split_indices <- function(group, n = 0L) {
+    .Call('plyr_split_indices', PACKAGE = 'plyr', group, n)
+}
+
diff --git a/R/colwise.r b/R/colwise.r
index 61343ea..211943b 100644
--- a/R/colwise.r
+++ b/R/colwise.r
@@ -79,4 +79,3 @@ catcolwise <- function(.fun, ...) {
 numcolwise <- function(.fun, ...) {
   colwise(.fun, is.numeric, ...)
 }
-
diff --git a/R/count.r b/R/count.r
index d94570e..5b9c286 100644
--- a/R/count.r
+++ b/R/count.r
@@ -36,7 +36,7 @@
 #' count(count(baseball[1:100,], c("id", "year")), "id", "freq")
 #' count(count(baseball, c("id", "year")), "freq")
 count <- function(df, vars = NULL, wt_var = NULL) {
-  if (is.vector(df)) {
+  if (is.atomic(df)) {
     df <- data.frame(x = df)
   }
 
diff --git a/R/id.r b/R/id.r
index 621e98c..a846b4b 100644
--- a/R/id.r
+++ b/R/id.r
@@ -37,6 +37,7 @@ id <- function(.variables, drop = FALSE) {
   # Calculate dimensions
   ndistinct <- vapply(ids, attr, "n", FUN.VALUE = numeric(1),
     USE.NAMES = FALSE)
+  
   n <- prod(ndistinct)
   if (n > 2 ^ 31) {
     # Too big for integers, have to use strings, which will be much slower :(
@@ -67,7 +68,8 @@ id_var <- function(x, drop = FALSE) {
   if (!is.null(attr(x, "n")) && !drop) return(x)
 
   if (is.factor(x) && !drop) {
-    id <- as.integer(addNA(x, ifany = TRUE))
+    x <- addNA(x, ifany = TRUE)
+    id <- as.integer(x)
     n <- length(levels(x))
   } else {
     levels <- sort(unique(x), na.last = TRUE)
diff --git a/R/idataframe.r b/R/idataframe.r
index b7a56d0..361ca0f 100644
--- a/R/idataframe.r
+++ b/R/idataframe.r
@@ -10,11 +10,6 @@
 #'
 #' @param df a data frame
 #' @return an immutable data frame
-#' @S3method [ idf
-#' @S3method names idf
-#' @S3method dim idf
-#' @S3method as.data.frame idf
-#' @S3method [[ idf
 #' @keywords manip
 #' @export
 #' @examples
@@ -44,6 +39,7 @@ idata.frame <- function(df) {
     class = c("idf", "environment"))
 }
 
+#' @export
 "[.idf" <- function(x, i, j, drop = TRUE) {
   # Single column special cases
   if (nargs() == 2) {
@@ -91,14 +87,18 @@ idata.frame <- function(df) {
     class = c("idf", "environment"))
 }
 
+#' @export
 names.idf <- function(x) x$`_cols`
 
+#' @export
 dim.idf <- function(x) c(length(x$`_rows`), length(x$`_cols`))
 
+#' @export
 as.data.frame.idf <- function(x, ...) {
   x$`_data`[x$`_rows`, x$`_cols`]
 }
 
+#' @export
 "[[.idf" <- function(x, i) {
   if (is.numeric(i)) {
     i <- names(x)[i]
diff --git a/R/indexed-array.r b/R/indexed-array.r
index 0e46b31..3180605 100644
--- a/R/indexed-array.r
+++ b/R/indexed-array.r
@@ -40,10 +40,10 @@ indexed_array <- function(env, index) {
   )
 }
 
-#' @S3method length indexed_array
+#' @export
 length.indexed_array <- function(x) nrow(x$index)
 
-#' @S3method [[ indexed_array
+#' @export
 "[[.indexed_array" <- function(x, i) {
   indices <- unname(x$index[i, , drop = TRUE])
   indices <- lapply(indices, function(x) if (x == "") bquote() else x)
@@ -55,5 +55,5 @@ length.indexed_array <- function(x) nrow(x$index)
   eval(call)
 }
 
-#' @S3method names indexed
+#' @export
 names.indexed_array <- function(x) rownames(x$index)
diff --git a/R/indexed-data-frame.r b/R/indexed-data-frame.r
index 519255d..cb36353 100644
--- a/R/indexed-data-frame.r
+++ b/R/indexed-data-frame.r
@@ -14,7 +14,7 @@ indexed_df <- function(data, index, vars) {
   )
 }
 
-#' @S3method [[ indexed_df
+#' @export
 "[[.indexed_df" <- function(x, i) {
   out <- extract_rows(x$data, x$index[[i]])
   attr(out, "vars") <- x$vars
diff --git a/R/indexed.r b/R/indexed.r
index d0c785c..f40bb15 100644
--- a/R/indexed.r
+++ b/R/indexed.r
@@ -1,7 +1,7 @@
-#' @S3method length indexed
+#' @export
 length.indexed <- function(x) length(x$index)
 
-#' @S3method names indexed
+#' @export
 names.indexed <- function(x) {
   labels <- attr(x, "split_labels")
   labels[] <- lapply(labels, as.character)
@@ -9,7 +9,7 @@ names.indexed <- function(x) {
   do.call(paste, c(labels, list(sep = ".")))
 }
 
-#' @S3method as.list indexed
+#' @export
 as.list.indexed <- function(x, ...) {
   n <- length(x)
   out <- vector("list", n)
@@ -21,12 +21,12 @@ as.list.indexed <- function(x, ...) {
   out
 }
 
-#' @S3method print indexed
+#' @export
 print.indexed <- function(x, ...) {
   print(as.list(x))
 }
 
-#' @S3method [ indexed
+#' @export
 "[.indexed" <- function(x, ...) {
   as.list(x)[...]
 }
diff --git a/R/l_ply.r b/R/l_ply.r
index 2293ff1..7caf2c9 100644
--- a/R/l_ply.r
+++ b/R/l_ply.r
@@ -25,6 +25,8 @@ l_ply <- function(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE,
       .paropts))
     fe <- eval(fe_call)
 
+    # Mute note about "no visible binding for d"
+    d <- NULL
     fe %dopar% .fun(d, ...)
   } else {
     .data <- as.list(.data)
diff --git a/R/ldply.r b/R/ldply.r
index 714a621..aa41412 100644
--- a/R/ldply.r
+++ b/R/ldply.r
@@ -6,13 +6,22 @@
 #' @template ply
 #' @template l-
 #' @template -d
+#' @param .id name of the index column (used if \code{.data} is a named list).
+#'   Pass \code{NULL} to avoid creation of the index column. For compatibility,
+#'   omit this argument or pass \code{NA} to avoid converting the index column
+#'   to a factor; in this case, \code{".id"} is used as colum name.
 #' @export
 ldply <- function(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE,
-                  .parallel = FALSE, .paropts = NULL) {
+                  .parallel = FALSE, .paropts = NULL, .id = NA) {
   if (!inherits(.data, "split")) .data <- as.list(.data)
   res <- llply(.data = .data, .fun = .fun, ...,
     .progress = .progress, .inform = .inform,
     .parallel = .parallel, .paropts = .paropts)
 
-  list_to_dataframe(res, attr(.data, "split_labels"))
+  if (is.na(.id)) {
+    .id <- ".id"
+    id_as_factor <- FALSE
+  } else
+    id_as_factor <- TRUE
+  list_to_dataframe(res, attr(.data, "split_labels"), .id, id_as_factor)
 }
diff --git a/R/list-to-array.r b/R/list-to-array.r
index fa75d4d..db353a1 100644
--- a/R/list-to-array.r
+++ b/R/list-to-array.r
@@ -39,7 +39,7 @@ list_to_array <- function(res, labels = NULL, .drop = FALSE) {
     in_dim <- n
   } else {
     in_labels <- lapply(labels,
-      function(x) if(is.factor(x)) levels(x) else sort(unique(x)))
+      function(x) if(is.factor(x)) levels(x) else sort(unique(x), na.last = TRUE))
     in_dim <- sapply(in_labels, length)
   }
 
diff --git a/R/list-to-dataframe.r b/R/list-to-dataframe.r
index 0abb240..c80b7ba 100644
--- a/R/list-to-dataframe.r
+++ b/R/list-to-dataframe.r
@@ -1,14 +1,16 @@
 #' List to data frame.
 #'
-#' Reduce/simplify a list of homogenous objects to a data frame.
-#' All \code{NULL} entries are removed. Remaining entries must be all atomic
+#' Reduce/simplify a list of homogenous objects to a data frame. All
+#' \code{NULL} entries are removed. Remaining entries must be all atomic
 #' or all data frames.
 #'
 #' @family list simplification functions
 #' @param res list of input data
 #' @param labels a data frame of labels, one row for each element of res
+#' @param idname the name of the index column, \code{NULL} for no index
+#'   column
 #' @keywords internal
-list_to_dataframe <- function(res, labels = NULL) {
+list_to_dataframe <- function(res, labels = NULL, id_name = NULL, id_as_factor = FALSE) {
   null <- vapply(res, is.null, logical(1))
   res <- res[!null]
   if (length(res) == 0) return(data.frame())
@@ -17,8 +19,13 @@ list_to_dataframe <- function(res, labels = NULL) {
     stopifnot(nrow(labels) == length(null))
     labels <- labels[!null, , drop = FALSE]
   }
-  if (is.null(labels) && !is.null(names(res))) {
-    labels <- data.frame(.id = names(res), stringsAsFactors = FALSE)
+  names_res <- names(res)
+  if (!is.null(id_name) && is.null(labels) && !is.null(names_res)) {
+    stopifnot(length(id_name) == 1)
+    if (id_as_factor)
+      names_res <- factor(names_res, levels = unique(names_res))
+    labels <- data.frame(.id = names_res, stringsAsFactors = FALSE)
+    names(labels) <- id_name
   }
 
   # Figure out how to turn elements into a data frame
diff --git a/R/loop-apply.r b/R/loop-apply.r
deleted file mode 100644
index 9905326..0000000
--- a/R/loop-apply.r
+++ /dev/null
@@ -1,13 +0,0 @@
-#' Loop apply
-#'
-#' An optimised version of lapply for the special case of operating on
-#' \code{seq_len(n)}
-#'
-#' @param n length of sequence
-#' @param f function to apply to each integer
-#' @param env environment in which to evaluate function
-#' @useDynLib plyr
-#' @keywords internal manip
-loop_apply <- function(n, f, env = parent.frame()) {
-  .Call("loop_apply", as.integer(n), f, env)
-}
diff --git a/R/plyr.r b/R/plyr.r
index 6a948d4..a161ca2 100644
--- a/R/plyr.r
+++ b/R/plyr.r
@@ -60,6 +60,7 @@
 #' }
 #'
 #' @docType package
+#' @importFrom Rcpp sourceCpp
 #' @name plyr
 NULL
 
diff --git a/R/quote.r b/R/quote.r
index 79eb313..dce3ed2 100644
--- a/R/quote.r
+++ b/R/quote.r
@@ -49,8 +49,7 @@ is.quoted <- function(x) inherits(x, "quoted")
 #' Display the \code{\link{str}}ucture of quoted variables
 #'
 #' @keywords internal
-#' @S3method print quoted
-#' @method print quoted
+#' @export
 print.quoted <- function(x, ...) str(x)
 
 #' Compute names of quoted variables.
@@ -60,8 +59,7 @@ print.quoted <- function(x, ...) str(x)
 #' variable names that can only be accessed using \code{``}.
 #'
 #' @keywords internal
-#' @S3method names quoted
-#' @method names quoted
+#' @export
 names.quoted <- function(x) {
   deparse2 <- function(x) paste(deparse(x), collapse = "")
   part_names <- unlist(lapply(x, deparse2))
@@ -116,7 +114,7 @@ eval.quoted <- function(exprs, envir = NULL, enclos = NULL, try = FALSE) {
 #' call objects.
 #'
 #' @return a list of quoted variables
-#' @seealso \code{\link{.}}
+#' @seealso \code{\link[=quoted]{.}}
 #' @param x input to quote
 #' @param env environment in which unbound symbols in expression should be
 #'   evaluated. Defaults to the environment in which \code{as.quoted} was
@@ -127,12 +125,12 @@ eval.quoted <- function(exprs, envir = NULL, enclos = NULL, try = FALSE) {
 #' as.quoted(a ~ b + log(d))
 as.quoted <- function(x, env = parent.frame()) UseMethod("as.quoted")
 
-#' @S3method as.quoted call
+#' @export
 as.quoted.call <- function(x, env = parent.frame()) {
   structure(as.list(x)[-1], env = env, class = "quoted")
 }
 
-#' @S3method as.quoted character
+#' @export
 as.quoted.character <- function(x, env = parent.frame()) {
   structure(
     lapply(x, function(x) parse(text = x)[[1]]),
@@ -140,12 +138,12 @@ as.quoted.character <- function(x, env = parent.frame()) {
   )
 }
 
-#' @S3method as.quoted numeric
+#' @export
 as.quoted.numeric <- function(x, env = parent.frame()) {
   structure(x, env = env, class = c("quoted", "numeric"))
 }
 
-#' @S3method as.quoted formula
+#' @export
 as.quoted.formula <- function(x, env = parent.frame()) {
   simplify <- function(x) {
     if (length(x) == 2 && x[[1]] == as.name("~")) {
@@ -166,31 +164,31 @@ as.quoted.formula <- function(x, env = parent.frame()) {
   structure(simplify(x), env = env, class = "quoted")
 }
 
-#' @S3method as.quoted quoted
+#' @export
 as.quoted.quoted <- function(x, env = parent.frame()) x
 
-#' @S3method as.quoted NULL
+#' @export
 as.quoted.NULL <- function(x, env = parent.frame()) {
   structure(list(), env = env, class = "quoted")
 }
 
-#' @S3method as.quoted name
+#' @export
 as.quoted.name <- function(x, env = parent.frame()) {
   structure(list(x), env = env, class = "quoted")
 }
 
-#' @S3method as.quoted factor
+#' @export
 as.quoted.factor <- function(x, env = parent.frame()) {
   as.quoted(as.character(x), env)
 }
 
-#' @S3method c quoted
+#' @export
 c.quoted <- function(..., recursive = FALSE) {
   structure(NextMethod("c"), class = "quoted",
     env = attr(list(...)[[1]], "env"))
 }
 
-#' @S3method [ quoted
+#' @export
 "[.quoted" <- function(x, i, ...) {
   structure(NextMethod("["), env = attr(x, "env"), class = "quoted")
 }
diff --git a/R/r_ply.r b/R/r_ply.r
index 83868db..c892f32 100644
--- a/R/r_ply.r
+++ b/R/r_ply.r
@@ -19,20 +19,8 @@
 #' r_ply(10, plot(runif(50)))
 #' r_ply(25, hist(runif(1000)))
 r_ply <- function(.n, .expr, .progress = "none", .print = FALSE) {
-  if (is.function(.expr)) {
-    f <- .expr
-  } else {
-    f <- eval.parent(substitute(function() .expr))
-  }
-
-  progress <- create_progress_bar(.progress)
-
-  progress$init(.n)
-  on.exit(progress$term())
-
-  for(i in seq_len(.n)) {
-    f()
-    progress$step()
-  }
-  progress$term()
+  .rlply_worker(.n, .progress,
+                eval.parent(substitute(function() .expr)),
+                .discard = TRUE, .print = .print)
+  invisible(NULL)
 }
diff --git a/R/raply.r b/R/raply.r
index 8cf24d7..bd94954 100644
--- a/R/raply.r
+++ b/R/raply.r
@@ -30,12 +30,7 @@
 #' hist(raply(1000, mean(rexp(100))))
 #' hist(raply(1000, mean(rexp(1000))))
 raply <- function(.n, .expr, .progress = "none", .drop = TRUE) {
-  if (is.function(.expr)) {
-    f <- .expr
-  } else {
-    f <- eval.parent(substitute(function() .expr))
-  }
-
-  res <- rlply(.n = .n, .expr = f, .progress = .progress)
+  res <- .rlply_worker(.n, .progress,
+                       eval.parent(substitute(function() .expr)))
   list_to_array(res, NULL, .drop)
 }
diff --git a/R/rbind-fill.r b/R/rbind-fill.r
index 5f80480..6cf2597 100644
--- a/R/rbind-fill.r
+++ b/R/rbind-fill.r
@@ -7,11 +7,19 @@
 #' operates substantially faster.
 #'
 #' Column names and types in the output will appear in the order in which
-#' they were encountered. No checking is performed to ensure that each column
-#' is of consistent type in the inputs.
+#' they were encountered.
+#'
+#' Unordered factor columns will have their levels unified and
+#' character data bound with factors will be converted to
+#' character. POSIXct data will be converted to be in the same time
+#' zone. Array and matrix columns must have identical dimensions after
+#' the row count. Aside from these there are no general checks that
+#' each column is of consistent data type.
 #'
 #' @param ... input data frames to row bind together.  The first argument can
 #'   be a list of data frames, in which case all other arguments are ignored.
+#'   Any NULL inputs are silently dropped. If all inputs are NULL, the output
+#'   is NULL.
 #' @keywords manip
 #' @family binding functions
 #' @return a single data frame
@@ -24,6 +32,7 @@ rbind.fill <- function(...) {
   if (is.list(dfs[[1]]) && !is.data.frame(dfs[[1]])) {
     dfs <- dfs[[1]]
   }
+  dfs <- compact(dfs)
 
   if (length(dfs) == 0) return()
   if (length(dfs) == 1) return(dfs[[1]])
@@ -40,9 +49,12 @@ rbind.fill <- function(...) {
   nrows <- sum(rows)
 
   # Generate output template
-  output <- output_template(dfs, nrows)
+  ot <- output_template(dfs, nrows)
+  setters <- ot$setters
+  getters <- ot$getters
+
   # Case of zero column inputs
-  if (length(output) == 0) {
+  if (length(setters) == 0) {
     return(as.data.frame(matrix(nrow = nrows, ncol = 0)))
   }
 
@@ -55,20 +67,14 @@ rbind.fill <- function(...) {
     df <- dfs[[i]]
 
     for(var in names(df)) {
-      if (!is.matrix(output[[var]])) {
-        if (is.factor(output[[var]]) && is.character(df[[var]])) {
-          output[[var]] <- as.character(output[[var]])
-        }
-        output[[var]][rng] <- df[[var]]
-      } else {
-        output[[var]][rng, ] <- df[[var]]
-      }
+      setters[[var]](rng, df[[var]])
     }
   }
 
-  quickdf(output)
+  quickdf(lapply(getters, function(x) x()))
 }
 
+# Construct named lists of setters and getters.
 output_template <- function(dfs, nrows) {
   vars <- unique(unlist(lapply(dfs, base::names)))   # ~ 125,000/s
   output <- vector("list", length(vars))
@@ -77,66 +83,151 @@ output_template <- function(dfs, nrows) {
   seen <- rep(FALSE, length(output))
   names(seen) <- vars
 
-  is_array <- seen
-  is_matrix <- seen
-  is_factor <- seen
-
   for(df in dfs) {
     matching <- intersect(names(df), vars[!seen])
     for(var in matching) {
-      value <- df[[var]]
-
-      if (is.vector(value) && is.atomic(value)) {
-        output[[var]] <- rep(NA, nrows)
-      } else if (is.factor(value)) {
-        output[[var]] <- factor(rep(NA, nrows), ordered = is.ordered(value))
-        is_factor[var] <- TRUE
-      } else if (is.matrix(value)) {
-        is_matrix[var] <- TRUE
-      } else if (is.array(value)) {
-        is_array[var] <- TRUE
-      } else if (inherits(value, "POSIXt")) {
-        output[[var]] <- as.POSIXct(rep(NA, nrows))
-        attr(output[[var]], "tzone") <- attr(value, "tzone")
-      } else if (is.list(value)) {
-        output[[var]] <- vector("list", nrows)
-      } else {
-        output[[var]] <- rep(NA, nrows)
-        class(output[[var]]) <- class(value)
-        attributes(output[[var]]) <- attributes(value)
-      }
+      output[[var]] <- allocate_column(df[[var]], nrows, dfs, var)
     }
 
     seen[matching] <- TRUE
     if (all(seen)) break  # Quit as soon as all done
   }
 
-  # Set up factors
-  for(var in vars[is_factor]) {
-    all <- unique(lapply(dfs, function(df) levels(df[[var]])))
-    output[[var]] <- factor(output[[var]], levels = unique(unlist(all)),
-      exclude = NULL)
+  list(setters=lapply(output, `[[`, "set"),
+       getters=lapply(output, `[[`, "get"))
+}
+
+# Allocate space for a column to be filled out by rbind.fill.
+#
+# @param example An example vector taken from the first data frame
+# @param nrows The number of rows
+# @param dfs The list of data frames that will be combined. This may
+# need to be scanned (to unify factor levels or check array dimension
+# consistency)
+# @param var The name of the column.
+#
+# @return A list of two accessor functions `list(set=<>, get=<>)`.
+# `.$set(rows, value)` stores data in the given rows.
+# `.$get()` retreives the column data.
+allocate_column <- function(example, nrows, dfs, var) {
+  #Compute the attributes of the column and allocate.  Returns a
+  #mutator function f(rows, values) rather than the actual allocated
+  #column.
+
+  a <- attributes(example)
+  type <- typeof(example)
+  class <- a$class
+  isList <- is.recursive(example)
+
+  a$names <- NULL
+  a$class <- NULL
+
+  if (is.data.frame(example)) {
+    stop("Data frame column '", var, "' not supported by rbind.fill")
   }
 
-  # Set up matrices
-  for(var in vars[is_matrix]) {
-    width <- unique(unlist(lapply(dfs, function(df) ncol(df[[var]]))))
-    if (length(width) > 1)
-      stop("Matrix variable ", var, " has inconsistent widths")
+  if (is.array(example)) {
+    if (length(dim(example)) > 1) {
+      if ("dimnames" %in% names(a)) {
+        a$dimnames[1] <- list(NULL)
+        if (!is.null(names(a$dimnames)))
+            names(a$dimnames)[1] <- ""
+      }
 
-    vec <- rep(NA, nrows * width)
-    output[[var]] <- array(vec, c(nrows, width))
+      # Check that all other args have consistent dims
+      df_has <- vapply(dfs, function(df) var %in% names(df), FALSE)
+      dims <- unique(lapply(dfs[df_has], function(df) dim(df[[var]])[-1]))
+      if (length(dims) > 1)
+          stop("Array variable ", var, " has inconsistent dims")
+
+      a$dim <- c(nrows, dim(example)[-1])
+      length <- prod(a$dim)
+    } else {
+      #1d arrays devolve into vectors
+      a$dim <- NULL
+      a$dimnames <- NULL
+      length <- nrows
+    }
+  } else {
+    length <- nrows
   }
 
-  # Set up arrays
-  for (var in vars[is_array]) {
-    dims <- unique(unlist(lapply(dfs, function(df) dims(df[[var]]))))
-    if (any(dims) > 1) {
-      stop("rbind.fill can only work with 1d arrays")
+  if (is.factor(example)) {
+    df_has <- vapply(dfs, function(df) var %in% names(df), FALSE)
+    isfactor <- vapply(dfs[df_has], function(df) is.factor(df[[var]]), FALSE)
+    if (all(isfactor)) {
+      #will be referenced by the mutator
+      levels <- unique(unlist(lapply(dfs[df_has],
+                                     function(df) levels(df[[var]]))))
+      a$levels <- levels
+      handler <- "factor"
+    } else {
+      #fall back on character
+      type <- "character"
+      handler <- "character"
+      class <- NULL
+      a$levels <- NULL
     }
+  } else if (inherits(example, "POSIXt")) {
+    tzone <- attr(example, "tzone")
+    class <- c("POSIXct", "POSIXt")
+    type <- "double"
+    handler <- "time"
+  } else {
+    handler <- type
+  }
 
-    output[[var]] <- rep(NA, nrows)
+  column <- vector(type, length)
+  if (!isList) {
+    column[] <- NA
+  }
+  attributes(column) <- a
+
+  #construct an assignment expression like `column[rows, ...] <- what`
+  #appropriate for the number of dims
+  assignment <- make_assignment_call(length(a$dim))
+
+  #It is especially important never to inspect the column when in the
+  #main rbind.fill loop. To avoid that, we've done specialization
+  #(figuring out the array assignment form and data type) ahead of
+  #time, and instead of returning the column, we return accessor
+  #functions that close over the column.
+  setter <- switch(
+      handler,
+      character = function(rows, what) {
+        what <- as.character(what)
+        eval(assignment)
+      },
+      factor = function(rows, what) {
+        #duplicate what `[<-.factor` does
+        what <- match(what, levels)
+        #no need to check since we already computed levels
+        eval(assignment)
+      },
+      time = function(rows, what) {
+        what <- as.POSIXct(what, tz = tzone)
+        eval(assignment)
+      },
+      function(rows, what) {
+        eval(assignment)
+      })
+
+  getter <- function() {
+    class(column) <<- class
+    column
   }
 
-  output
+  list(set=setter, get=getter)
+}
+
+#construct an assignment expression like `column[rows, ...] <- what`
+#appropriate for the number of dims
+make_assignment_call <- function(ndims) {
+  assignment <- quote(column[rows] <<- what)
+  if (ndims >= 2) {
+    assignment[[2]] <- as.call(
+        c(as.list(assignment[[2]]),
+          rep(list(quote(expr = )), ndims - 1)))
+  }
+  assignment
 }
diff --git a/R/rdply.r b/R/rdply.r
index edd3bf9..7f4525b 100644
--- a/R/rdply.r
+++ b/R/rdply.r
@@ -2,34 +2,37 @@
 #'
 #' Evalulate expression n times then combine results into a data frame
 #'
-#' This function runs an expression multiple times, and combines the
-#' result into a data frame.  If there are no results, then this function
-#' returns a data frame with zero rows and columns (\code{data.frame()}).
-#' This function is equivalent to \code{\link{replicate}}, but will always
-#' return results as a data frame.
+#' This function runs an expression multiple times, and combines the result into
+#' a data frame.  If there are no results, then this function returns a data
+#' frame with zero rows and columns (\code{data.frame()}). This function is
+#' equivalent to \code{\link{replicate}}, but will always return results as a
+#' data frame.
 #'
 #'
 #' @keywords manip
 #' @param .n number of times to evaluate the expression
 #' @param .expr expression to evaluate
-#' @param .progress name of the progress bar to use, see \code{\link{create_progress_bar}}
+#' @param .progress name of the progress bar to use, see
+#'   \code{\link{create_progress_bar}}
+#' @param .id name of the index column. Pass \code{NULL} to avoid creation of
+#'   the index column. For compatibility, omit this argument or pass \code{NA}
+#'   to avoid converting the index column to a factor; in this case, \code{".n"}
+#'   is used as colum name..
 #' @return a data frame
 #' @export
-#' @references Hadley Wickham (2011). The Split-Apply-Combine Strategy for
-#'   Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+#' @references Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data
+#'   Analysis. Journal of Statistical Software, 40(1), 1-29.
 #'   \url{http://www.jstatsoft.org/v40/i01/}.
 #' @examples
 #' rdply(20, mean(runif(100)))
 #' rdply(20, each(mean, var)(runif(100)))
 #' rdply(20, data.frame(x = runif(2)))
-rdply <- function(.n, .expr, .progress = "none") {
-  if (is.function(.expr)) {
-    f <- .expr
-  } else {
-    f <- eval.parent(substitute(function() .expr))
-  }
-
-  res <- rlply(.n = .n, .expr = f, .progress = .progress)
+rdply <- function(.n, .expr, .progress = "none", .id = NA) {
+  res <- .rlply_worker(.n, .progress,
+                       eval.parent(substitute(function() .expr)))
+  names(res) <- seq_len(.n)
   labels <- data.frame(.n = seq_len(.n))
+  if (!is.na(.id))
+    names(labels) <- .id
   list_to_dataframe(res, labels)
 }
diff --git a/R/revalue.r b/R/revalue.r
index c57adf0..4f4a0f5 100644
--- a/R/revalue.r
+++ b/R/revalue.r
@@ -75,7 +75,7 @@ mapvalues <- function(x, from, to, warn_missing = TRUE) {
 
   if (is.factor(x)) {
     # If x is a factor, call self but operate on the levels
-    levels(x) <- mapvalues(levels(x), from, to)
+    levels(x) <- mapvalues(levels(x), from, to, warn_missing)
     return(x)
   }
 
diff --git a/R/rlply.r b/R/rlply.r
index 80905c0..a2a3bfc 100644
--- a/R/rlply.r
+++ b/R/rlply.r
@@ -21,22 +21,89 @@
 #' mods <- rlply(100, lm(y ~ x, data=data.frame(x=rnorm(100), y=rnorm(100))))
 #' hist(laply(mods, function(x) summary(x)$r.squared))
 rlply <- function(.n, .expr, .progress = "none") {
-  if (is.function(.expr)) {
-    f <- .expr
-  } else {
-    f <- eval.parent(substitute(function() .expr))
-  }
+  res <- .rlply_worker(.n, .progress,
+                       eval.parent(substitute(function() .expr)))
+  res
+}
+
+.rlply_worker <- function(.n, .progress, .expr_wrap, .print = FALSE,
+                          .discard = FALSE) {
+  if (!is.vector(.n, "numeric") || length(.n) > 1L)
+    stop(".n must be an integer vector of length 1")
+  if (.n == 0L)
+    return (list())
 
   progress <- create_progress_bar(.progress)
-  result <- vector("list", length = .n)
 
   progress$init(.n)
   on.exit(progress$term())
 
-  for(i in seq_len(.n)) {
-    result[i] <- list(f())
+  if (.print) {
+    wrap <- function(f) function() { print(f()) }
+  } else {
+    wrap <- identity
+  }
+
+  # The logic below is responsible for ascertaining that .expr is evaluated
+  # exactly .n times, whether it's a function or an expression.  (See GitHub
+  # issue #158.)  When the function .rlply_worker is called, the .expr_wrap
+  # argument is a function that returns the .expr argument passed to the calling
+  # r*ply function.  The .wrapped_expr_to_fun function will convert the
+  # .expr_wrap argument to a list that contains a function and the result of the
+  # first evaluation, which is necessary because there seems to be no other way
+  # to find out if .expr is a function or an expression without evaluating it at
+  # least once.  After that, only .n - 1 further evaluations are necessary.
+  #
+  # In addition, results are printed and/or discareded depending on the `wrap`
+  # function defined above.
+  fun <- .wrapped_expr_to_fun(.expr_wrap)
+  f <- wrap(fun$f)
+
+  if (.discard) {
+    wrap(function() fun$val)()
+    progress$step()
+
+    for(i in seq.int(from = 2L, length.out = .n - 1L)) {
+      f()
+      progress$step()
+    }
+
+    invisible(NULL)
+  } else {
+    result <- vector("list", length = .n)
+    result[1L] <- list(wrap(function() fun$val)())
     progress$step()
+
+    for(i in seq.int(from = 2L, length.out = .n - 1L)) {
+      result[i] <- list(f())
+      progress$step()
+    }
+
+    result
   }
+}
 
-  result
+#' r*ply helper function
+#'
+#' Call a function to check if the result is a function or an expression, to
+#' support expressions as arguments to the r*ply family.
+#'
+#' @param .expr_wrap function to call
+#' @return named list with two components. f -- function, val -- result of first
+#'   evaluation
+#' @noRd
+.wrapped_expr_to_fun <- function(.expr_wrap) {
+  # When .expr_wrap is evaluated, it will return either a function or an
+  # expression.  In the first case, this function is assigned to the f
+  # component, and also called once explicitly to assign the val component.  In
+  # the second case, this has been already the first evaluation of .expr -- the
+  # parameter wrapped by .expr_wrap; the results are reused for the val
+  # component, and the wrapped function is assigned to f.
+  res <- .expr_wrap()
+
+  if (is.function(res)) {
+    list(f = res, val = res())
+  } else {
+    list(f = .expr_wrap, val = res)
+  }
 }
diff --git a/R/round-any.r b/R/round-any.r
index d748e76..8ab29e7 100644
--- a/R/round-any.r
+++ b/R/round-any.r
@@ -24,12 +24,12 @@ round_any <- function(x, accuracy, f = round) {
   UseMethod("round_any")
 }
 
-#' @S3method round_any numeric
+#' @export
 round_any.numeric <- function(x, accuracy, f = round) {
   f(x / accuracy) * accuracy
 }
 
-#' @S3method round_any POSIXct
+#' @export
 round_any.POSIXct <- function(x, accuracy, f = round) {
   tz <- format(x[1], "%Z")
   xr <- round_any(as.numeric(x), accuracy, f)
diff --git a/R/split-indices.r b/R/split-indices.r
deleted file mode 100644
index 2c6e4db..0000000
--- a/R/split-indices.r
+++ /dev/null
@@ -1,18 +0,0 @@
-#' Split indices.
-#'
-#' An optimised version of split for the special case of splitting row
-#' indices into groups, as used by \code{\link{splitter_d}}
-#'
-#' @param index integer indices
-#' @param group integer groups
-#' @param n largest integer (may not appear in index)
-#' @useDynLib plyr
-#' @keywords internal manip
-#' @export
-split_indices <- function(group, n = max(group)) {
-  if (length(group) == 0) return(integer())
-  stopifnot(is.integer(group))
-  n <- as.integer(n)
-
-  .Call("split_indices", group, as.integer(n))
-}
diff --git a/R/splitter-d.r b/R/splitter-d.r
index b3b6edf..3f49321 100644
--- a/R/splitter-d.r
+++ b/R/splitter-d.r
@@ -85,6 +85,7 @@ split_labels <- function(splits, drop, id = plyr::id(splits, drop = TRUE)) {
 
 ulevels <- function(x) {
   if (is.factor(x)) {
+    x <- addNA(x, ifany = TRUE)
     levs <- levels(x)
     factor(levs, levels = levs)
   } else {
diff --git a/R/summarise.r b/R/summarise.r
index a409148..d6f0962 100644
--- a/R/summarise.r
+++ b/R/summarise.r
@@ -1,15 +1,18 @@
 #' Summarise a data frame.
 #'
-#' Summarise works in an analagous way to transform, except instead of adding
-#' columns to an existing data frame, it creates a new data frame.  This is
-#' particularly useful in conjunction with \code{\link{ddply}} as it makes it
-#' easy to perform group-wise summaries.
+#' Summarise works in an analogous way to \code{\link{mutate}}, except
+#' instead of adding columns to an existing data frame, it creates a new
+#' data frame.  This is particularly useful in conjunction with
+#' \code{\link{ddply}} as it makes it easy to perform group-wise summaries.
 #'
 #' @param .data the data frame to be summarised
 #' @param ... further arguments of the form var = value
 #' @keywords manip
 #' @aliases summarise summarize
 #' @export summarise summarize
+#' @note Be careful when using existing variable names; the corresponding 
+#' columns will be immediately updated with the new data and this can affect
+#' subsequent operations referring to those variables.
 #' @examples
 #' # Let's extract the number of teams and total period of time
 #' # covered by the baseball dataframe
diff --git a/README.md b/README.md
index 117f44d..682866d 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
+[![Build Status](https://travis-ci.org/hadley/plyr.png?branch=master)](https://travis-ci.org/hadley/plyr)
+
 # plyr
 
 plyr is a set of tools for a common set of problems: you need to __split__ up a big data structure into homogeneous pieces, __apply__ a function to each piece and then __combine__ all the results back together. For example, you might want to:
diff --git a/inst/tests/test-array.r b/inst/tests/test-array.r
index 55c90ca..5ebf731 100644
--- a/inst/tests/test-array.r
+++ b/inst/tests/test-array.r
@@ -133,12 +133,12 @@ test_that("single column data frames work when treated as an array", {
 
 test_that("aaply equivalent to apply with correct permutation", {
   a <- matrix(seq_len(400), ncol = 20)
-  expect_that(rowMeans(a), equals(aaply(a, 1, mean), check.attr = FALSE))
-  expect_that(colMeans(a), equals(aaply(a, 2, mean), check.attr = FALSE))
+  expect_equivalent(rowMeans(a), aaply(a, 1, mean))
+  expect_equivalent(colMeans(a), aaply(a, 2, mean))
 
   b <- structure(a, dimnames = amv_dimnames(a))
-  expect_that(rowMeans(b), equals(aaply(b, 1, mean), check.attr = FALSE))
-  expect_that(colMeans(b), equals(aaply(b, 2, mean), check.attr = FALSE))
+  expect_equivalent(rowMeans(b), aaply(b, 1, mean))
+  expect_equivalent(colMeans(b), aaply(b, 2, mean))
 })
 
 test_that("array reconstruction correct with missing cells", {
diff --git a/inst/tests/test-count.r b/inst/tests/test-count.r
index 9339ea1..8c4c498 100644
--- a/inst/tests/test-count.r
+++ b/inst/tests/test-count.r
@@ -47,3 +47,17 @@ test_that("weighted count matches xtab", {
   expect_that(ct2, equals(xt2))
 
 })
+
+test_that("count works with factors and dates", {
+  genders <- c("Female", "Male")
+  n <- c(5, 10)
+  gender_data <- factor(rep.int(genders, n))
+    
+  expect_equal(count(gender_data), data.frame(x = genders, freq = n))
+ 
+  this_week <- seq(Sys.Date(), Sys.Date() + 6, "1 day")
+  n2 <- 1:7
+  day_data <- rep(this_week, n2)
+  
+  expect_equal(count(day_data), data.frame(x = this_week, freq = n2))
+})
diff --git a/inst/tests/test-data-frame.r b/inst/tests/test-data-frame.r
index fdd9c85..88baaf0 100644
--- a/inst/tests/test-data-frame.r
+++ b/inst/tests/test-data-frame.r
@@ -60,3 +60,16 @@ test_that("label variables always preserved", {
 
 
 })
+
+# Test for #140
+test_that(".id column can be renamed", {
+  l <- llply(1:4, function(i) rep(i, i))
+  names(l) <- 1:4
+  f <- function(l) data.frame(sum=sum(unlist(l)))
+  
+  out1 <- ldply(l, f)
+  out2 <- ldply(l, f, .id='x')
+  
+  expect_equal(names(out1), c('.id', 'sum'))
+  expect_equal(names(out2), c('x', 'sum'))
+})
diff --git a/inst/tests/test-join.r b/inst/tests/test-join.r
index aa0d47d..26ff8d3 100644
--- a/inst/tests/test-join.r
+++ b/inst/tests/test-join.r
@@ -164,3 +164,22 @@ test_that("column orders are common, x only, y only", {
   expect_equal(names(right2), c("a", "b", "c"))
 
 })
+
+test_that("strings match to factors", {
+
+  dfF <- data.frame(character = c("Aeryn", "Jothee", "Jothee",
+                      "Chiana", "Scorpius", "Scorpius"),
+                    species = c("Sebacian", "Luxan", "Sebacian",
+                      "Nibari", "Sebacian", "Scarran"),
+                    stringsAsFactors = TRUE)
+  dfS <- colwise(as.character)(dfF)
+  matchF <- data.frame(species = "Sebacian", stringsAsFactors = TRUE)
+  matchS <- colwise(as.character)(matchF)
+
+  #nor does `join`, (so inner joins are not commutative)
+  expect_equal(3, nrow(join(dfF, matchF, type = "inner", by="species")))
+  expect_equal(3, nrow(join(dfS, matchS, type = "inner", by="species")))
+  expect_equal(3, nrow(join(dfS, matchF, type = "inner", by="species")))
+  expect_equal(3, nrow(join(dfF, matchS, type = "inner", by="species")))
+
+})
diff --git a/inst/tests/test-list.r b/inst/tests/test-list.r
index c3edb63..d24db56 100644
--- a/inst/tests/test-list.r
+++ b/inst/tests/test-list.r
@@ -19,3 +19,14 @@ test_that("list names are preserved", {
   expect_that(names(llply(a)), equals(letters[1:10]))
 
 })
+
+# Test for #142
+test_that(".n column can be renamed", {
+  f <- function() data.frame(r=runif(1))
+  
+  out1 <- rdply(4, f)
+  out2 <- rdply(4, f, .id='x')
+  
+  expect_equal(names(out1), c('.n', 'r'))
+  expect_equal(names(out2), c('x', 'r'))
+})
diff --git a/inst/tests/test-mutate.r b/inst/tests/test-mutate.r
index c58bc82..385b9ec 100644
--- a/inst/tests/test-mutate.r
+++ b/inst/tests/test-mutate.r
@@ -2,11 +2,11 @@ context("Mutate")
 
 test_that("mutate behaves the same as transform", {
   m1 <- mutate(airquality, Ozone = -Ozone)
-  t1 <- mutate(airquality, Ozone = -Ozone)
+  t1 <- transform(airquality, Ozone = -Ozone)
   expect_that(m1, equals(t1))
 
   m2 <- mutate(airquality, new = -Ozone, Temp = (Temp-32)/1.8)
-  t2 <- mutate(airquality, new = -Ozone, Temp = (Temp-32)/1.8)
+  t2 <- transform(airquality, new = -Ozone, Temp = (Temp-32)/1.8)
   expect_that(m2, equals(t2))
 })
 
diff --git a/inst/tests/test-ninteraction.r b/inst/tests/test-ninteraction.r
index 961935e..1d924f0 100644
--- a/inst/tests/test-ninteraction.r
+++ b/inst/tests/test-ninteraction.r
@@ -55,6 +55,11 @@ test_that("NAs are placed last", {
   expect_that(id_var(c(NA, 1)), is_equivalent_to(c(2, 1)))
 })
 
+test_that("factor with missing levels has correct count", {
+  id <- id_var(factor(1, NA))
+  expect_equal(attr(id, "n"), 1)
+})
+
 test_that("zero length input gives single number", {
   expect_that(id(character()), is_equivalent_to(integer()))
 })
diff --git a/inst/tests/test-parallel.r b/inst/tests/test-parallel.r
index 793808c..7057cfc 100644
--- a/inst/tests/test-parallel.r
+++ b/inst/tests/test-parallel.r
@@ -3,11 +3,13 @@ context("Parallel")
 if (require("doMC", quietly = TRUE)) {
   registerDoMC(2)
 
-  test_that("l_ply respects .parallel", {
-    expect_that(
-      l_ply(c(0.1, 0.1), Sys.sleep, .parallel = TRUE),
-      takes_less_than(0.15))
-  })
+  if (identical(Sys.getenv("NOT_CRAN"), "true")) {
+    test_that("l_ply respects .parallel", {
+      expect_that(
+        l_ply(c(0.1, 0.1), Sys.sleep, .parallel = TRUE),
+        takes_less_than(0.15))
+    })
+  }
 
   test_that("l_ply + .parallel complains about invalid arguments", {
     expect_message(
diff --git a/inst/tests/test-rbind.r b/inst/tests/test-rbind.r
index deb03fa..3d655cd 100644
--- a/inst/tests/test-rbind.r
+++ b/inst/tests/test-rbind.r
@@ -55,6 +55,28 @@ test_that("matrices are preserved", {
   expect_that(ab1, equals(ab2))
 })
 
+test_that("character or factor or list-matrices are preserved", {
+  d1 <- data.frame(a=1:2,
+                   x=I(matrix(c('a', 'b', 'c', 'd'), nrow=2)))
+  d2 <- data.frame(b=1:2,
+                   x=I(`dim<-`(factor(c('a', 'b', 'c', 'd')), c(2,2))))
+  d3 <- data.frame(b=1:2,
+                   x=I(array(as.list(1:4), c(2,2))))
+
+  b1 <- rbind.fill(d1, d1)
+  b2 <- rbind.fill(d2, d2)
+  b3 <- rbind.fill(d3, d3)
+
+  expect_equal(dim(b1$x), c(4,2))
+  expect_equal(typeof(b1$x), "character")
+
+  expect_equal(dim(b2$x), c(4,2))
+  expect_is(b2$x, "factor")
+
+  expect_equal(dim(b3$x), c(4,2))
+  expect_equal(typeof(b3$x), "list")
+})
+
 test_that("missing levels in factors preserved", {
   f <- addNA(factor(c("a", "b", NA)))
   df1 <- data.frame(a = f)
@@ -68,7 +90,7 @@ test_that("time zones are preserved", {
 
   get_tz <- function(x) attr(as.POSIXlt(x), "tz")
 
-  tzs <- c("", "CET", "UTC")
+  tzs <- c("CET", "UTC")
   for(tz in tzs) {
     start <- data.frame(x = as.POSIXct(dstart, tz = tz))
     end <- data.frame(x = as.POSIXct(dstop, tz = tz))
@@ -79,12 +101,54 @@ test_that("time zones are preserved", {
 
 })
 
-test_that("arrays are ok", {
+test_that("1d arrays treated as vectors", {
   df <- data.frame(x = 1)
   df$x <- array(1, 1)
 
+  #1d arrays converted into vectors
   df2 <- rbind.fill(df, df)
   expect_that(df2$x, is_equivalent_to(rbind(df, df)$x))
+  expect_that(dim(df2$x), equals(dim(rbind(df, df)$x)))
+
+  #if dims are stripped, dimnames should be also
+  df <- data.frame(x = 1)
+  df$x <- array(2, 1, list(x="one"))
+  df2 <- rbind.fill(df, df)
+  expect_that(is.null(dimnames(df2$x)), is_true())
+
+  #can bind 1d array to vector
+  dfV <- data.frame(x=3)
+  dfO1 <- rbind.fill(df, dfV)
+  dfO2 <- rbind.fill(dfV, df)
+  expect_equal(dfO1, data.frame(x=c(2, 3)))
+  expect_equal(dfO2, data.frame(x=c(3, 2)))
+})
+
+test_that("multidim arrays ok", {
+  library(abind)
+  df <- data.frame(x = 1:3)
+  df$x <- array(1:27, c(3,3,3))
+
+  df2 <- rbind.fill(df, df)
+  expect_equal(dim(df2$x), dim(abind(along=1, df$x, df$x)))
+  expect_that(df2$x, is_equivalent_to(abind(along=1, df$x, df$x)))
+ })
+
+test_that("Array column names preserved", {
+  x <- data.frame(hair.color=dimnames(HairEyeColor)[[1]])
+  x$obs <- HairEyeColor[,,1]
+
+  xx1 <- rbind(x, x)
+  xx2 <- rbind.fill(x, x)
+
+  #plyr is against row names, but should respect col names like rbind
+  rownames(xx1) <- NULL
+  rownames(xx1$obs) <- NULL
+
+  #but unlike rbind it should also preserve names-of-dimnames.
+  names(dimnames(xx1$obs)) <- c("", "Eye")
+
+  expect_equal(xx1, xx2)
 })
 
 test_that("attributes are preserved", {
@@ -101,21 +165,37 @@ test_that("attributes are preserved", {
 
   expect_that(attr(d12$b, "foo"), equals("one"))
   expect_that(attr(d21$b, "foo"), equals("two"))
-
 })
 
-test_that("characters override factors", {
+test_that("characters override and convert factors", {
   d1a <- data.frame(x=c('a','b'), y=1:2)
-  d2a <- data.frame(x=c('b','d'), z=1:2, stringsAsFactors=F)
+  d2a <- data.frame(x=c('c','d'), z=1:2, stringsAsFactors=F)
 
   d1b <- data.frame(x=c('a','b'), y=1:2, stringsAsFactors=F)
-  d2b <- data.frame(x=c('b','d'), z=1:2)
+  d2b <- data.frame(x=c('c','d'), z=1:2)
 
   d3a <- rbind.fill(d1a,d2a)
   d3b <- rbind.fill(d1b,d2b)
 
-  expect_that(d3a$x, is_a("character"))
-  expect_that(d3b$x, is_a("character"))
+  expect_equal(d3a$x, c("a", "b", "c", "d"))
+  expect_equal(d3b$x, c("a", "b", "c", "d"))
+})
+
+test_that("factor to character conversion preserves attributes", {
+  d1 <- data.frame(a = letters[1:10], b = factor(letters[11:20]),
+                   stringsAsFactors=FALSE)
+  d2 <- data.frame(a = factor(letters[11:20]), b = letters[11:20],
+                   stringsAsFactors=FALSE)
+
+  attr(d1$a, "foo") <- "one"
+  attr(d1$b, "foo") <- "two"
+  attr(d2$a, "foo") <- "bar"
+  attr(d2$b, "foo") <- "baz"
+
+  d12 <- rbind.fill(d1, d2)
+
+  expect_equal(attr(d12$a, "foo"), "one")
+  expect_equal(attr(d12$b, "foo"), "two")
 })
 
 test_that("zero row data frames ok", {
@@ -157,3 +237,75 @@ test_that("zero col data frames ok", {
   expect_equal(nrow(zb), 1)
   expect_equal(nrow(zc), 1)
 })
+
+test_that("rbind.fill rejects non-vector columns", {
+  a <- list(a=list(1), b=c(3), c="d", f=function() NULL)
+  attr(a, "row.names") <- c(NA_integer_, -1)
+  class(a) <- "data.frame"
+  expect_error(rbind.fill(a,a), "cannot make")
+})
+
+test_that("rbind.fill rejects data frame columns", {
+  a <- data.frame(a=1:3, b=2:4, c=3:5)
+  a$c <- data.frame(x=10:12, y=11:13)
+  rownames(a) <- NULL
+  rownames(a$c) <- NULL
+  expect_error(rbind.fill(a,a), "not supported")
+})
+
+rbind_time <- function(size,
+                       classes = c("numeric", "character",
+                                   "array", "factor", "time")) {
+  unit <- quickdf(list(numeric = 1:3,
+                       character = c("a", "b", "c"),
+                       array = array(1:6, c(3,2)),
+                       factor = factor(c("a", "b", "c")),
+                       time = as.POSIXct(Sys.time()) + 1:3))
+  args <- rep(list(unit[classes]), size)
+  system.time(do.call(rbind.fill, args))
+}
+
+get_rbind_times <- function(...) {
+  rbind_time(10) #warm up/JIT
+  mdply(.fun = rbind_time, ...)
+}
+
+if (identical(Sys.getenv("NOT_CRAN"), "true") &&
+    !identical(Sys.getenv("TRAVIS"), "true")) {
+
+expect_linear_enough <- function(timings, size=2^10, threshold=0.2) {
+  #expect that no more than `threshold` of a `size` input's runtime is
+  #accounted for by quadratic behavior
+  #predict.lm(type="terms") does strange things w/ built-in intercepts, avoid
+  timings <- mutate(timings, intercept=1)
+  model <- lm(user.self ~ size + I(size^2) - 1 + intercept, timings)
+  p <- predict(model, newdata=data.frame(size=size, intercept=1), type="terms")
+  expect_that(p[2] / p[1] < threshold, is_true(), NULL, NULL)
+}
+
+test_that("rbind.fill performance linear", {
+  timings <- get_rbind_times(data.frame(size = 2^(1:10)),
+                             classes=c("numeric", "character", "array"))
+  expect_linear_enough(timings)
+})
+
+test_that("rbind.fill performance linear with factors", {
+  timings <- get_rbind_times(data.frame(size = 2^(1:10)),
+                             classes=c("factor"))
+  expect_linear_enough(timings)
+})
+
+test_that("rbind.fill performance linear with times", {
+  timings <- get_rbind_times(data.frame(size = 2^(1:10)),
+                             classes=c("time"))
+  expect_linear_enough(timings)
+})
+
+test_that("NULLs silently dropped", {
+  expect_equal(rbind.fill(mtcars, NULL), mtcars)
+  expect_equal(rbind.fill(NULL, mtcars), mtcars)
+  expect_equal(rbind.fill(NULL, NULL), NULL)
+
+})
+
+}
diff --git a/inst/tests/test-replicate.r b/inst/tests/test-replicate.r
index ebee4ce..800703c 100644
--- a/inst/tests/test-replicate.r
+++ b/inst/tests/test-replicate.r
@@ -7,3 +7,9 @@ test_that("length of results are correct", {
   expect_equal(length(a), 4)
   expect_equal(length(b), 4)
 })
+
+test_that("name of id column is set", {
+  df <- rdply(4, function() c(a=1), .id='index')
+  
+  expect_equal(names(df), c('index', 'a'))
+})
diff --git a/inst/tests/test-revalue.r b/inst/tests/test-revalue.r
index b56c9bf..a2e3603 100644
--- a/inst/tests/test-revalue.r
+++ b/inst/tests/test-revalue.r
@@ -118,3 +118,20 @@ test_that("revalue and mapvalues accept empty vectors and NULL", {
   expect_identical(revalue(NULL, c("3"=30), warn_missing=FALSE), NULL)
   expect_identical(mapvalues(NULL, 3, 30, warn_missing=FALSE), NULL)
 })
+
+test_that("revalue and mapvalues respect warn_missing", {
+  # revalue
+  expect_that(revalue("a", c("a"="A")), not(shows_message()))
+  expect_that(revalue("a", c("b"="B"), warn_missing=TRUE), shows_message())
+  expect_that(revalue("a", c("b"="B"), warn_missing=FALSE), not(shows_message()))
+
+  # mapvalues
+  expect_that(mapvalues("a", "a", "A"), not(shows_message()))
+  expect_that(mapvalues("a", "b", "B", warn_missing=TRUE), shows_message())
+  expect_that(mapvalues("a", "b", "B", warn_missing=FALSE), not(shows_message()))
+
+  # mapvalues with factors
+  expect_that(mapvalues(factor("a"), "a", "A"), not(shows_message()))
+  expect_that(mapvalues(factor("a"), "b", "B", warn_missing=TRUE), shows_message())
+  expect_that(mapvalues(factor("a"), "b", "B", warn_missing=FALSE), not(shows_message()))
+})
diff --git a/inst/tests/test-rply.r b/inst/tests/test-rply.r
new file mode 100644
index 0000000..dc0b4f8
--- /dev/null
+++ b/inst/tests/test-rply.r
@@ -0,0 +1,146 @@
+context("r?ply")
+
+test_that("Side effects for r_ply", {
+  counts <- c(0, 1, 5)
+
+  # Simple function with side effect of incrementing i in an outer environment
+  # by one
+  inc <- function() { i <<- i + 1; invisible(NULL) }
+
+  # For each of the possible counts, check that exactly n side effects are seen
+  # for various types of invocations of inc: As a statement, as a function call
+  # or as a function calling the function.  Calling r_ply with a function that
+  # returns the inc function should not produce any side effects, this is
+  # intentional.
+  for (n in counts) {
+    i <- 0
+    r_ply(n, inc)
+    expect_equal(i, n, info="inc")
+
+    i <- 0
+    r_ply(n, inc())
+    expect_equal(i, n, info="inc()")
+
+    i <- 0
+    r_ply(n, inc() + inc())
+    expect_equal(i, 2 * n, info="inc() + inc()")
+
+    i <- 0
+    r_ply(n, function() inc())
+    expect_equal(i, n, info="function() inc()")
+
+    i <- 0
+    r_ply(n, function() inc() + inc())
+    expect_equal(i, 2 * n, info="function() inc() + inc()")
+
+    i <- 0
+    r_ply(n, function() inc)
+    expect_equal(i, 0, info="function() inc")
+  }
+})
+
+test_that("Side effects for rlply", {
+  counts <- c(0, 1, 5)
+
+  # Similar to the test for r_ply, now there is also a return value in incition
+  # to the side effect
+  inc <- function() { i <<- i + 1 }
+
+  # The test now checks, in incition to side effect count, that the returned
+  # list is correct
+  for (n in counts) {
+    i <- 0
+    res <- rlply(n, inc)
+    expect_equal(res, as.list(seq_len(n)), info="inc")
+    expect_equal(i, n, info="inc")
+
+    i <- 0
+    res <- rlply(n, inc())
+    expect_equal(res, as.list(seq_len(n)), info="inc()")
+    expect_equal(i, n, info="inc()")
+
+    i <- 0
+    res <- rlply(n, function() inc())
+    expect_equal(res, as.list(seq_len(n)), info="function() inc()")
+    expect_equal(i, n, info="function() inc()")
+
+    # Funny case: A function that returns a function, this is not
+    # handled at all
+    i <- 0
+    rlply(n, function() inc)
+    expect_equal(i, 0, info="function() inc")
+  }
+})
+
+test_that("Side effects for raply", {
+  counts <- c(0, 1, 5)
+  
+  inc <- function() { i <<- i + 1 }
+  
+  for (n in counts) {
+    # This is funny. Why does raply(.n, inc) return a named vector only for
+    # .n == 1?
+    if (n == 0) {
+      exp_res <- logical()
+    } else if (n == 1) {
+      exp_res <- setNames(nm = 1)
+    } else
+      exp_res <- seq_len(n)
+    
+    i <- 0
+    res <- raply(n, inc)
+    expect_equal(res, exp_res, info="inc")
+    expect_equal(i, n, info="inc")
+    
+    i <- 0
+    res <- raply(n, inc())
+    expect_equal(res, exp_res, info="inc()")
+    expect_equal(i, n, info="inc()")
+    
+    i <- 0
+    res <- raply(n, function() inc())
+    expect_equal(res, exp_res, info="function() inc()")
+    expect_equal(i, n, info="function() inc()")
+  }
+})
+
+test_that("Side effects for rdply", {
+  counts <- c(0, 1, 5)
+  
+  inc <- function() { i <<- i + 1; data.frame(i = i) }
+  
+  for (n in counts) {
+    if (n == 0) {
+      exp_res <- data.frame()
+    } else {
+      exp_res <- data.frame(.n = 1L:n, i = 1L:n, stringsAsFactors = FALSE)
+    }
+    
+    i <- 0
+    res <- rdply(n, inc)
+    expect_equal(res, exp_res, info="inc")
+    expect_equal(i, n, info="inc")
+    
+    i <- 0
+    res <- rdply(n, inc())
+    expect_equal(res, exp_res, info="inc()")
+    expect_equal(i, n, info="inc()")
+    
+    i <- 0
+    res <- rdply(n, function() inc())
+    expect_equal(res, exp_res, info="function() inc()")
+    expect_equal(i, n, info="function() inc()")
+  }
+})
+
+test_that("Invalid arguments for r_ply", {
+  expect_error(r_ply(-3, identity))
+  expect_error(r_ply("abc", identity))
+  expect_error(r_ply(c(1,2), identity))
+  expect_error(r_ply(list(5), identity))
+})
+
+test_that(".id column for rdply", {
+  expect_equal(rdply(5, 10)$.n, 1:5)
+  expect_equal(rdply(5, 10, .id=".x")$.x, 1:5)
+})
diff --git a/inst/tests/test-simplify-df.r b/inst/tests/test-simplify-df.r
index b4fb7b4..b37b556 100644
--- a/inst/tests/test-simplify-df.r
+++ b/inst/tests/test-simplify-df.r
@@ -103,15 +103,15 @@ test_that("names preserved and filled for atomic vectors", {
 })
 
 test_that("names captured from list", {
-  li <- list(a = 1:5, b = 5:10, c = 5:15)
+  li <- list(c = 5:15, b = 5:10, a = 1:5)
 
   df <- ldply(li, function(x) mean(x))
-  expect_that(df$.id, equals(c("a", "b", "c")))
+  expect_that(df$.id, equals(names(li)))
 
   df <- ldply(li, function(x) {
       if (any(x >= 10)) mean(x)
   })
-  expect_that(df$.id, equals(c("b", "c")))
+  expect_that(df$.id, equals(names(li)[-3]))
 })
 
 test_that("correct number of rows outputted", {
@@ -121,8 +121,7 @@ test_that("correct number of rows outputted", {
   expect_that(nrow(res), equals(3))
 })
 
-
-test_that("matrices converted to data frames", {
+test_that("matrices converted to data frames, without id column", {
   mat <- matrix(1:20, ncol = 4)
   colnames(mat) <- letters[1:4]
 
@@ -130,5 +129,29 @@ test_that("matrices converted to data frames", {
   df <- list_to_dataframe(li)
 
   expect_equal(nrow(df), 2 * nrow(mat))
-  expect_equal(names(df), c(".id", "a", "b", "c", "d"))
+  expect_equal(names(df), c("a", "b", "c", "d"))
+})
+
+test_that("matrices converted to data frames, with id column", {
+  mat <- matrix(1:20, ncol = 4)
+  colnames(mat) <- letters[1:4]
+  
+  li <- list(a = mat, b = mat)
+  df <- plyr:::list_to_dataframe(li, id_name = "my_id")
+  
+  expect_equal(nrow(df), 2 * nrow(mat))
+  expect_equal(names(df), c("my_id", "a", "b", "c", "d"))
+  expect_equal(df$my_id, rep(c("a", "b"), c(5, 5)))
+})
+
+test_that("matrices converted to data frames, with id column as factor", {
+  mat <- matrix(1:20, ncol = 4)
+  colnames(mat) <- letters[1:4]
+  
+  li <- list(a = mat, b = mat)
+  df <- list_to_dataframe(li, id_name = "my_id", id_as_factor = TRUE)
+  
+  expect_equal(nrow(df), 2 * nrow(mat))
+  expect_equal(names(df), c("my_id", "a", "b", "c", "d"))
+  expect_equal(levels(df$my_id), c("a", "b"))
 })
diff --git a/inst/tests/test-split-indices.r b/inst/tests/test-split-indices.r
index 04f8f69..53d5b26 100644
--- a/inst/tests/test-split-indices.r
+++ b/inst/tests/test-split-indices.r
@@ -1,7 +1,14 @@
 context("Split indices")
 
 test_that("Error if n too small", {
-  expect_error(split_indices(1:10, 5),
-    "n smaller than largest index")
+  expect_error(split_indices(1:10, -5), "n must be")
+})
+
+test_that("index expands if n too small", {
+  expect_equal(split_indices(1:10, 5), as.list(1:10))
+})
 
+test_that("succeeds for large number of groups", {
+  i <- 2097142
+  expect_equal(length(split_indices(seq_len(i), i)), i)
 })
diff --git a/man/a_ply.Rd b/man/a_ply.Rd
index e9e1e8e..762b21f 100644
--- a/man/a_ply.Rd
+++ b/man/a_ply.Rd
@@ -1,10 +1,11 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{a_ply}
 \alias{a_ply}
 \title{Split array, apply function, and discard results.}
 \usage{
-  a_ply(.data, .margins, .fun = NULL, ..., .expand = TRUE,
-    .progress = "none", .inform = FALSE, .print = FALSE,
-    .parallel = FALSE, .paropts = NULL)
+a_ply(.data, .margins, .fun = NULL, ..., .expand = TRUE,
+  .progress = "none", .inform = FALSE, .print = FALSE,
+  .parallel = FALSE, .paropts = NULL)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -45,11 +46,10 @@
   \code{FALSE})}
 }
 \value{
-  Nothing
+Nothing
 }
 \description{
-  For each slice of an array, apply function and discard
-  results
+For each slice of an array, apply function and discard results
 }
 \section{Input}{
   This function splits matrices, arrays and data frames by
@@ -62,16 +62,16 @@
   displaying plots or saving output.
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  Other array input: \code{\link{aaply}},
-  \code{\link{adply}}, \code{\link{alply}}
+Other array input: \code{\link{aaply}};
+  \code{\link{adply}}; \code{\link{alply}}
 
-  Other no output: \code{\link{d_ply}},
-  \code{\link{l_ply}}, \code{\link{m_ply}}
+Other no output: \code{\link{d_ply}}; \code{\link{l_ply}};
+  \code{\link{m_ply}}
 }
 \keyword{manip}
 
diff --git a/man/aaply.Rd b/man/aaply.Rd
index 4ce52ff..dab029b 100644
--- a/man/aaply.Rd
+++ b/man/aaply.Rd
@@ -1,10 +1,11 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{aaply}
 \alias{aaply}
 \title{Split array, apply function, and return results in an array.}
 \usage{
-  aaply(.data, .margins, .fun = NULL, ..., .expand = TRUE,
-    .progress = "none", .inform = FALSE, .drop = TRUE,
-    .parallel = FALSE, .paropts = NULL)
+aaply(.data, .margins, .fun = NULL, ..., .expand = TRUE,
+  .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE,
+  .paropts = NULL)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -46,22 +47,19 @@
   \code{TRUE}}
 }
 \value{
-  if results are atomic with same type and dimensionality,
-  a vector, matrix or array; otherwise, a list-array (a
-  list with dimensions)
+if results are atomic with same type and dimensionality, a
+  vector, matrix or array; otherwise, a list-array (a list with
+  dimensions)
 }
 \description{
-  For each slice of an array, apply function, keeping
-  results as an array.
+For each slice of an array, apply function, keeping results as an array.
 }
 \details{
-  This function is very similar to \code{\link{apply}},
-  except that it will always return an array, and when the
-  function returns >1 d data structures, those dimensions
-  are added on to the highest dimensions, rather than the
-  lowest dimensions.  This makes \code{aaply} idempotent,
-  so that \code{aaply(input, X, identity)} is equivalent to
-  \code{aperm(input, X)}.
+This function is very similar to \code{\link{apply}}, except that it will
+always return an array, and when the function returns >1 d data structures,
+those dimensions are added on to the highest dimensions, rather than the
+lowest dimensions.  This makes \code{aaply} idempotent, so that
+\code{aaply(input, X, identity)} is equivalent to \code{aperm(input, X)}.
 }
 \section{Input}{
   This function splits matrices, arrays and data frames by
@@ -92,16 +90,16 @@ aaply(ozone, 1:2, standardise)
 aaply(ozone, 1:2, diff)
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  Other array input: \code{\link{a_ply}},
-  \code{\link{adply}}, \code{\link{alply}}
+Other array input: \code{\link{a_ply}};
+  \code{\link{adply}}; \code{\link{alply}}
 
-  Other array output: \code{\link{daply}},
-  \code{\link{laply}}, \code{\link{maply}}
+Other array output: \code{\link{daply}};
+  \code{\link{laply}}; \code{\link{maply}}
 }
 \keyword{manip}
 
diff --git a/man/adply.Rd b/man/adply.Rd
index 434f94d..59d73f5 100644
--- a/man/adply.Rd
+++ b/man/adply.Rd
@@ -1,10 +1,11 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{adply}
 \alias{adply}
 \title{Split array, apply function, and return results in a data frame.}
 \usage{
-  adply(.data, .margins, .fun = NULL, ..., .expand = TRUE,
-    .progress = "none", .inform = FALSE, .parallel = FALSE,
-    .paropts = NULL)
+adply(.data, .margins, .fun = NULL, ..., .expand = TRUE,
+  .progress = "none", .inform = FALSE, .parallel = FALSE,
+  .paropts = NULL)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -42,11 +43,11 @@
   variable.}
 }
 \value{
-  A data frame, as described in the output section.
+A data frame, as described in the output section.
 }
 \description{
-  For each slice of an array, apply function then combine
-  results into a data frame.
+For each slice of an array, apply function then combine results into a data
+frame.
 }
 \section{Input}{
   This function splits matrices, arrays and data frames by
@@ -66,16 +67,16 @@
   (\code{data.frame()}).
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  Other array input: \code{\link{a_ply}},
-  \code{\link{aaply}}, \code{\link{alply}}
+Other array input: \code{\link{a_ply}};
+  \code{\link{aaply}}; \code{\link{alply}}
 
-  Other data frame output: \code{\link{ddply}},
-  \code{\link{ldply}}, \code{\link{mdply}}
+Other data frame output: \code{\link{ddply}};
+  \code{\link{ldply}}; \code{\link{mdply}}
 }
 \keyword{manip}
 
diff --git a/man/alply.Rd b/man/alply.Rd
index 3afdfa7..c4467be 100644
--- a/man/alply.Rd
+++ b/man/alply.Rd
@@ -1,10 +1,11 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{alply}
 \alias{alply}
 \title{Split array, apply function, and return results in a list.}
 \usage{
-  alply(.data, .margins, .fun = NULL, ..., .expand = TRUE,
-    .progress = "none", .inform = FALSE, .parallel = FALSE,
-    .paropts = NULL, .dims = FALSE)
+alply(.data, .margins, .fun = NULL, ..., .expand = TRUE,
+  .progress = "none", .inform = FALSE, .parallel = FALSE,
+  .paropts = NULL, .dims = FALSE)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -45,20 +46,20 @@
   names from input.}
 }
 \value{
-  list of results
+list of results
 }
 \description{
-  For each slice of an array, apply function then combine
-  results into a list.
+For each slice of an array, apply function then combine results into a
+list.
 }
 \details{
-  The list will have "dims" and "dimnames" corresponding to
-  the margins given. For instance \code{alply(x, c(3,2),
-  ...)} where \code{x} has dims \code{c(4,3,2)} will give a
-  result with dims \code{c(2,3)}.
+The list will have "dims" and "dimnames" corresponding to the
+margins given. For instance \code{alply(x, c(3,2), ...)} where
+\code{x} has dims \code{c(4,3,2)} will give a result with dims
+\code{c(2,3)}.
 
-  \code{alply} is somewhat similar to \code{\link{apply}}
-  for cases where the results are not atomic.
+\code{alply} is somewhat similar to \code{\link{apply}} for cases
+where the results are not atomic.
 }
 \section{Input}{
   This function splits matrices, arrays and data frames by
@@ -74,16 +75,16 @@ alply(ozone, 3, quantile)
 alply(ozone, 3, function(x) table(round(x)))
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  Other array input: \code{\link{a_ply}},
-  \code{\link{aaply}}, \code{\link{adply}}
+Other array input: \code{\link{a_ply}};
+  \code{\link{aaply}}; \code{\link{adply}}
 
-  Other list output: \code{\link{dlply}},
-  \code{\link{llply}}, \code{\link{mlply}}
+Other list output: \code{\link{dlply}};
+  \code{\link{llply}}; \code{\link{mlply}}
 }
 \keyword{manip}
 
diff --git a/man/amv_dim.Rd b/man/amv_dim.Rd
index 87878cb..e123ff9 100644
--- a/man/amv_dim.Rd
+++ b/man/amv_dim.Rd
@@ -1,14 +1,15 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{amv_dim}
 \alias{amv_dim}
 \title{Dimensions.}
 \usage{
-  amv_dim(x)
+amv_dim(x)
 }
 \arguments{
   \item{x}{array, matrix or vector}
 }
 \description{
-  Consistent dimensions for vectors, matrices and arrays.
+Consistent dimensions for vectors, matrices and arrays.
 }
 \keyword{internal}
 
diff --git a/man/amv_dimnames.Rd b/man/amv_dimnames.Rd
index 627dc58..e797881 100644
--- a/man/amv_dimnames.Rd
+++ b/man/amv_dimnames.Rd
@@ -1,20 +1,20 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{amv_dimnames}
 \alias{amv_dimnames}
 \title{Dimension names.}
 \usage{
-  amv_dimnames(x)
+amv_dimnames(x)
 }
 \arguments{
   \item{x}{array, matrix or vector}
 }
 \description{
-  Consistent dimnames for vectors, matrices and arrays.
+Consistent dimnames for vectors, matrices and arrays.
 }
 \details{
-  Unlike \code{\link{dimnames}} no part of the output will
-  ever be null.  If a component of dimnames is omitted,
-  \code{amv_dimnames} will return an integer sequence of
-  the appropriate length.
+Unlike \code{\link{dimnames}} no part of the output will ever be
+null.  If a component of dimnames is omitted, \code{amv_dimnames}
+will return an integer sequence of the appropriate length.
 }
 \keyword{internal}
 
diff --git a/man/arrange.Rd b/man/arrange.Rd
index 4418af4..1e62f54 100644
--- a/man/arrange.Rd
+++ b/man/arrange.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{arrange}
 \alias{arrange}
 \title{Order a data frame by its colums.}
 \usage{
-  arrange(df, ...)
+arrange(df, ...)
 }
 \arguments{
   \item{df}{data frame to reorder}
@@ -11,11 +12,10 @@
   \code{df} and then fed to \code{\link{order}}}
 }
 \description{
-  This function completes the subsetting, transforming and
-  ordering triad with a function that works in a similar
-  way to \code{\link{subset}} and \code{\link{transform}}
-  but for reordering a data frame by its columns. This
-  saves a lot of typing!
+This function completes the subsetting, transforming and ordering triad
+with a function that works in a similar way to \code{\link{subset}} and
+\code{\link{transform}} but for reordering a data frame by its columns.
+This saves a lot of typing!
 }
 \examples{
 # sort mtcars data by cylinder and displacement
@@ -30,8 +30,7 @@ arrange(myCars, cyl, disp)
 arrange(myCars, cyl, desc(disp))
 }
 \seealso{
-  \code{\link{order}} for sorting function in the base
-  package
+\code{\link{order}} for sorting function in the base package
 }
 \keyword{manip}
 
diff --git a/man/as.data.frame.function.Rd b/man/as.data.frame.function.Rd
index a078294..5b8bce0 100644
--- a/man/as.data.frame.function.Rd
+++ b/man/as.data.frame.function.Rd
@@ -1,9 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{as.data.frame.function}
 \alias{as.data.frame.function}
 \title{Make a function return a data frame.}
 \usage{
-  \method{as.data.frame}{function} (x, row.names, optional,
-    ...)
+\method{as.data.frame}{function}(x, row.names, optional, ...)
 }
 \arguments{
   \item{x}{function to make return a data frame}
@@ -17,13 +17,12 @@
   \item{...}{necessary to match the generic, but not used}
 }
 \description{
-  Create a new function that returns the existing function
-  wrapped in a data.frame
+Create a new function that returns the existing function wrapped in a
+data.frame
 }
 \details{
-  This is useful when calling \code{*dply} functions with a
-  function that returns a vector, and you want the output
-  in rows, rather than columns
+This is useful when calling \code{*dply} functions with a function that
+returns a vector, and you want the output in rows, rather than columns
 }
 \keyword{manip}
 
diff --git a/man/as.list.split.Rd b/man/as.list.split.Rd
index 3fdf6af..d7dd12b 100644
--- a/man/as.list.split.Rd
+++ b/man/as.list.split.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{as.list.split}
 \alias{as.list.split}
 \title{Convert split list to regular list.}
 \usage{
-  \method{as.list}{split} (x, ...)
+\method{as.list}{split}(x, ...)
 }
 \arguments{
   \item{x}{object to convert to a list}
@@ -10,8 +11,7 @@
   \item{...}{unused}
 }
 \description{
-  Strip off label related attributed to make a strip list
-  as regular list
+Strip off label related attributed to make a strip list as regular list
 }
 \keyword{internal}
 
diff --git a/man/as.quoted.Rd b/man/as.quoted.Rd
index 8063b5e..8c93983 100644
--- a/man/as.quoted.Rd
+++ b/man/as.quoted.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{as.quoted}
 \alias{as.quoted}
 \title{Convert input to quoted variables.}
 \usage{
-  as.quoted(x, env = parent.frame())
+as.quoted(x, env = parent.frame())
 }
 \arguments{
   \item{x}{input to quote}
@@ -12,25 +13,23 @@
   environment in which \code{as.quoted} was executed.}
 }
 \value{
-  a list of quoted variables
+a list of quoted variables
 }
 \description{
-  Convert characters, formulas and calls to quoted
-  .variables
+Convert characters, formulas and calls to quoted .variables
 }
 \details{
-  This method is called by default on all plyr functions
-  that take a \code{.variables} argument, so that
-  equivalent forms can be used anywhere.
+This method is called by default on all plyr functions that take a
+\code{.variables} argument, so that equivalent forms can be used anywhere.
 
-  Currently conversions exist for character vectors,
-  formulas and call objects.
+Currently conversions exist for character vectors, formulas and
+call objects.
 }
 \examples{
 as.quoted(c("a", "b", "log(d)"))
 as.quoted(a ~ b + log(d))
 }
 \seealso{
-  \code{\link{.}}
+\code{\link[=quoted]{.}}
 }
 
diff --git a/man/baseball.Rd b/man/baseball.Rd
index f9c6a19..a24d60a 100644
--- a/man/baseball.Rd
+++ b/man/baseball.Rd
@@ -1,15 +1,17 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \docType{data}
 \name{baseball}
 \alias{baseball}
 \title{Yearly batting records for all major league baseball players}
 \format{A 21699 x 22 data frame}
+\usage{
+baseball
+}
 \description{
-  This data frame contains batting statistics for a subset
-  of players collected from
-  \url{http://www.baseball-databank.org/}. There are a
-  total of 21,699 records, covering 1,228 players from 1871
-  to 2007. Only players with more 15 seasons of play are
-  included.
+This data frame contains batting statistics for a subset of players
+collected from \url{http://www.baseball-databank.org/}. There are a total
+of 21,699 records, covering 1,228 players from 1871 to 2007. Only players
+with more 15 seasons of play are included.
 }
 \section{Variables}{
   Variables: \itemize{ \item id, unique player id \item
@@ -48,7 +50,7 @@ model(baberuth)
 models <- dlply(baseball, .(id), model)
 }
 \references{
-  \url{http://www.baseball-databank.org/}
+\url{http://www.baseball-databank.org/}
 }
 \keyword{datasets}
 
diff --git a/man/colwise.Rd b/man/colwise.Rd
index 7e71b61..84b0f4a 100644
--- a/man/colwise.Rd
+++ b/man/colwise.Rd
@@ -1,14 +1,15 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{colwise}
 \alias{catcolwise}
 \alias{colwise}
 \alias{numcolwise}
 \title{Column-wise function.}
 \usage{
-  colwise(.fun, .cols = true, ...)
+colwise(.fun, .cols = true, ...)
 
-  catcolwise(.fun, ...)
+catcolwise(.fun, ...)
 
-  numcolwise(.fun, ...)
+numcolwise(.fun, ...)
 }
 \arguments{
   \item{.fun}{function}
@@ -20,13 +21,12 @@
   \item{...}{other arguments passed on to \code{.fun}}
 }
 \description{
-  Turn a function that operates on a vector into a function
-  that operates column-wise on a data.frame.
+Turn a function that operates on a vector into a function that operates
+column-wise on a data.frame.
 }
 \details{
-  \code{catcolwise} and \code{numcolwise} provide version
-  that only operate on discrete and numeric variables
-  respectively.
+\code{catcolwise} and \code{numcolwise} provide version that only operate
+on discrete and numeric variables respectively.
 }
 \examples{
 # Count number of missing values
diff --git a/man/compact.Rd b/man/compact.Rd
index 4c3bd74..14dfa87 100644
--- a/man/compact.Rd
+++ b/man/compact.Rd
@@ -1,14 +1,15 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{compact}
 \alias{compact}
 \title{Compact list.}
 \usage{
-  compact(l)
+compact(l)
 }
 \arguments{
   \item{l}{list}
 }
 \description{
-  Remove all NULL entries from a list
+Remove all NULL entries from a list
 }
 \keyword{internal}
 \keyword{manip}
diff --git a/man/count.Rd b/man/count.Rd
index f6018fa..8877a52 100644
--- a/man/count.Rd
+++ b/man/count.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{count}
 \alias{count}
 \title{Count the number of occurences.}
 \usage{
-  count(df, vars = NULL, wt_var = NULL)
+count(df, vars = NULL, wt_var = NULL)
 }
 \arguments{
   \item{df}{data frame to be processed}
@@ -14,22 +15,21 @@
   for each combination of id variables.}
 }
 \value{
-  a data frame with label and freq columns
+a data frame with label and freq columns
 }
 \description{
-  Equivalent to \code{as.data.frame(table(x))}, but does
-  not include combinations with zero counts.
+Equivalent to \code{as.data.frame(table(x))}, but does not include
+combinations with zero counts.
 }
 \details{
-  Speed-wise count is competitive with \code{\link{table}}
-  for single variables, but it really comes into its own
-  when summarising multiple dimensions because it only
-  counts combinations that actually occur in the data.
+Speed-wise count is competitive with \code{\link{table}} for single
+variables, but it really comes into its own when summarising multiple
+dimensions because it only counts combinations that actually occur in the
+data.
 
-  Compared to \code{\link{table}} +
-  \code{\link{as.data.frame}}, \code{count} also preserves
-  the type of the identifier variables, instead of
-  converting them to characters/factors.
+Compared to \code{\link{table}} + \code{\link{as.data.frame}}, \code{count}
+also preserves the type of the identifier variables, instead of converting
+them to characters/factors.
 }
 \examples{
 # Count of each value of "id" in the first 100 cases
@@ -47,8 +47,7 @@ count(count(baseball[1:100,], c("id", "year")), "id", "freq")
 count(count(baseball, c("id", "year")), "freq")
 }
 \seealso{
-  \code{\link{table}} for related functionality in the base
-  package
+\code{\link{table}} for related functionality in the base package
 }
 \keyword{manip}
 
diff --git a/man/create_progress_bar.Rd b/man/create_progress_bar.Rd
index 17a1806..5ebef45 100644
--- a/man/create_progress_bar.Rd
+++ b/man/create_progress_bar.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{create_progress_bar}
 \alias{create_progress_bar}
 \title{Create progress bar.}
 \usage{
-  create_progress_bar(name = "none", ...)
+create_progress_bar(name = "none", ...)
 }
 \arguments{
   \item{name}{type of progress bar to create}
@@ -11,30 +12,26 @@
   function}
 }
 \description{
-  Create progress bar object from text string.
+Create progress bar object from text string.
 }
 \details{
-  Progress bars give feedback on how apply step is
-  proceeding.  This is mainly useful for long running
-  functions, as for short functions, the time taken up by
-  splitting and combining may be on the same order (or
-  longer) as the apply step.  Additionally, for short
-  functions, the time needed to update the progress bar can
-  significantly slow down the process. For the trivial
-  examples below, using the tk progress bar slows things
-  down by a factor of a thousand.
+Progress bars give feedback on how apply step is proceeding.  This
+is mainly useful for long running functions, as for short functions, the
+time taken up by splitting and combining may be on the same order (or
+longer) as the apply step.  Additionally, for short functions, the time
+needed to update the progress bar can significantly slow down the process.
+For the trivial examples below, using the tk progress bar slows things down
+by a factor of a thousand.
 
-  Note the that progress bar is approximate, and if the
-  time taken by individual function applications is highly
-  non-uniform it may not be very informative of the time
-  left.
+Note the that progress bar is approximate, and if the time taken by
+individual function applications is highly non-uniform it may not be very
+informative of the time left.
 
-  There are currently four types of progress bar: "none",
-  "text", "tk", and "win".  See the individual
-  documentation for more details.  In plyr functions, these
-  can either be specified by name, or you can create the
-  progress bar object yourself if you want more control
-  over its apperance. See the examples.
+There are currently four types of progress bar:  "none", "text", "tk", and
+"win".  See the individual documentation for more details.  In plyr
+functions, these can either be specified by name, or you can create the
+progress bar object yourself if you want more control over its apperance.
+See the examples.
 }
 \examples{
 # No progress bar
@@ -49,8 +46,7 @@ l_ply(1:100, identity, .progress = "text")
 l_ply(1:10000, identity, .progress = progress_text(char = "."))
 }
 \seealso{
-  \code{\link{progress_none}}, \code{\link{progress_text}},
-  \code{\link{progress_tk}}, \code{\link{progress_win}}
+\code{\link{progress_none}}, \code{\link{progress_text}}, \code{\link{progress_tk}}, \code{\link{progress_win}}
 }
 \keyword{utilities}
 
diff --git a/man/d_ply.Rd b/man/d_ply.Rd
index aa078e8..3e9f6f5 100644
--- a/man/d_ply.Rd
+++ b/man/d_ply.Rd
@@ -1,10 +1,11 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{d_ply}
 \alias{d_ply}
 \title{Split data frame, apply function, and discard results.}
 \usage{
-  d_ply(.data, .variables, .fun = NULL, ...,
-    .progress = "none", .inform = FALSE, .drop = TRUE,
-    .print = FALSE, .parallel = FALSE, .paropts = NULL)
+d_ply(.data, .variables, .fun = NULL, ..., .progress = "none",
+  .inform = FALSE, .drop = TRUE, .print = FALSE, .parallel = FALSE,
+  .paropts = NULL)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -43,11 +44,10 @@
   \code{FALSE})}
 }
 \value{
-  Nothing
+Nothing
 }
 \description{
-  For each subset of a data frame, apply function and
-  discard results
+For each subset of a data frame, apply function and discard results
 }
 \section{Input}{
   This function splits data frames by variables.
@@ -59,16 +59,16 @@
   displaying plots or saving output.
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  Other data frame input: \code{\link{daply}},
-  \code{\link{ddply}}, \code{\link{dlply}}
+Other data frame input: \code{\link{daply}};
+  \code{\link{ddply}}; \code{\link{dlply}}
 
-  Other no output: \code{\link{a_ply}},
-  \code{\link{l_ply}}, \code{\link{m_ply}}
+Other no output: \code{\link{a_ply}}; \code{\link{l_ply}};
+  \code{\link{m_ply}}
 }
 \keyword{manip}
 
diff --git a/man/daply.Rd b/man/daply.Rd
index 393d11d..2420af7 100644
--- a/man/daply.Rd
+++ b/man/daply.Rd
@@ -1,10 +1,11 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{daply}
 \alias{daply}
 \title{Split data frame, apply function, and return results in an array.}
 \usage{
-  daply(.data, .variables, .fun = NULL, ...,
-    .progress = "none", .inform = FALSE, .drop_i = TRUE,
-    .drop_o = TRUE, .parallel = FALSE, .paropts = NULL)
+daply(.data, .variables, .fun = NULL, ..., .progress = "none",
+  .inform = FALSE, .drop_i = TRUE, .drop_o = TRUE, .parallel = FALSE,
+  .paropts = NULL)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -43,15 +44,14 @@
   \code{TRUE}}
 }
 \value{
-  if results are atomic with same type and dimensionality,
-  a vector, matrix or array; otherwise, a list-array (a
-  list with dimensions)
+if results are atomic with same type and dimensionality, a
+  vector, matrix or array; otherwise, a list-array (a list with
+  dimensions)
 }
 \description{
-  For each subset of data frame, apply function then
-  combine results into an array.  \code{daply} with a
-  function that operates column-wise is similar to
-  \code{\link{aggregate}}.
+For each subset of data frame, apply function then combine results into
+an array.  \code{daply} with a function that operates column-wise is
+similar to \code{\link{aggregate}}.
 }
 \section{Input}{
   This function splits data frames by variables.
@@ -72,16 +72,16 @@ daply(baseball[, 6:9], .(baseball$year), colwise(mean))
 daply(baseball, .(year), function(df) colwise(mean)(df[, 6:9]))
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  Other array output: \code{\link{aaply}},
-  \code{\link{laply}}, \code{\link{maply}}
+Other array output: \code{\link{aaply}};
+  \code{\link{laply}}; \code{\link{maply}}
 
-  Other data frame input: \code{\link{d_ply}},
-  \code{\link{ddply}}, \code{\link{dlply}}
+Other data frame input: \code{\link{d_ply}};
+  \code{\link{ddply}}; \code{\link{dlply}}
 }
 \keyword{manip}
 
diff --git a/man/ddply.Rd b/man/ddply.Rd
index c89b5d8..0b6430e 100644
--- a/man/ddply.Rd
+++ b/man/ddply.Rd
@@ -1,10 +1,10 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{ddply}
 \alias{ddply}
 \title{Split data frame, apply function, and return results in a data frame.}
 \usage{
-  ddply(.data, .variables, .fun = NULL, ...,
-    .progress = "none", .inform = FALSE, .drop = TRUE,
-    .parallel = FALSE, .paropts = NULL)
+ddply(.data, .variables, .fun = NULL, ..., .progress = "none",
+  .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -40,11 +40,11 @@
   (TRUE, default)}
 }
 \value{
-  A data frame, as described in the output section.
+A data frame, as described in the output section.
 }
 \description{
-  For each subset of a data frame, apply function then
-  combine results into a data frame.
+For each subset of a data frame, apply function then combine results into a
+data frame.
 }
 \section{Input}{
   This function splits data frames by variables.
@@ -95,19 +95,18 @@ base2 <- ddply(baseball, .(id), mutate,
 )
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  \code{\link{tapply}} for similar functionality in the
-  base package
+\code{\link{tapply}} for similar functionality in the base package
 
-  Other data frame input: \code{\link{d_ply}},
-  \code{\link{daply}}, \code{\link{dlply}}
+Other data frame input: \code{\link{d_ply}};
+  \code{\link{daply}}; \code{\link{dlply}}
 
-  Other data frame output: \code{\link{adply}},
-  \code{\link{ldply}}, \code{\link{mdply}}
+Other data frame output: \code{\link{adply}};
+  \code{\link{ldply}}; \code{\link{mdply}}
 }
 \keyword{manip}
 
diff --git a/man/defaults.Rd b/man/defaults.Rd
index c3e5dce..382c6d4 100644
--- a/man/defaults.Rd
+++ b/man/defaults.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{defaults}
 \alias{defaults}
 \title{Set defaults.}
 \usage{
-  defaults(x, y)
+defaults(x, y)
 }
 \arguments{
   \item{x}{list of values}
@@ -10,8 +11,7 @@
   \item{y}{defaults}
 }
 \description{
-  Convient method for combining a list of values with their
-  defaults.
+Convient method for combining a list of values with their defaults.
 }
 \keyword{manip}
 
diff --git a/man/desc.Rd b/man/desc.Rd
index 242153e..67528c7 100644
--- a/man/desc.Rd
+++ b/man/desc.Rd
@@ -1,15 +1,15 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{desc}
 \alias{desc}
 \title{Descending order.}
 \usage{
-  desc(x)
+desc(x)
 }
 \arguments{
   \item{x}{vector to transform}
 }
 \description{
-  Transform a vector into a format that will be sorted in
-  descending order.
+Transform a vector into a format that will be sorted in descending order.
 }
 \examples{
 desc(1:10)
diff --git a/man/dims.Rd b/man/dims.Rd
index 1734380..7ba6cf2 100644
--- a/man/dims.Rd
+++ b/man/dims.Rd
@@ -1,14 +1,15 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{dims}
 \alias{dims}
 \title{Number of dimensions.}
 \usage{
-  dims(x)
+dims(x)
 }
 \arguments{
   \item{x}{array}
 }
 \description{
-  Number of dimensions of an array or vector
+Number of dimensions of an array or vector
 }
 \keyword{internal}
 
diff --git a/man/dlply.Rd b/man/dlply.Rd
index 6fcaff7..0798ac2 100644
--- a/man/dlply.Rd
+++ b/man/dlply.Rd
@@ -1,10 +1,10 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{dlply}
 \alias{dlply}
 \title{Split data frame, apply function, and return results in a list.}
 \usage{
-  dlply(.data, .variables, .fun = NULL, ...,
-    .progress = "none", .inform = FALSE, .drop = TRUE,
-    .parallel = FALSE, .paropts = NULL)
+dlply(.data, .variables, .fun = NULL, ..., .progress = "none",
+  .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -40,13 +40,12 @@
   (TRUE, default)}
 }
 \value{
-  list of results
+list of results
 }
 \description{
-  For each subset of a data frame, apply function then
-  combine results into a list. \code{dlply} is similar to
-  \code{\link{by}} except that the results are returned in
-  a different format.
+For each subset of a data frame, apply function then combine results into a
+list. \code{dlply} is similar to \code{\link{by}} except that the results
+are returned in a different format.
 }
 \section{Input}{
   This function splits data frames by variables.
@@ -69,16 +68,16 @@ qual <- laply(models, function(mod) summary(mod)$r.squared)
 hist(qual)
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  Other data frame input: \code{\link{d_ply}},
-  \code{\link{daply}}, \code{\link{ddply}}
+Other data frame input: \code{\link{d_ply}};
+  \code{\link{daply}}; \code{\link{ddply}}
 
-  Other list output: \code{\link{alply}},
-  \code{\link{llply}}, \code{\link{mlply}}
+Other list output: \code{\link{alply}};
+  \code{\link{llply}}; \code{\link{mlply}}
 }
 \keyword{manip}
 
diff --git a/man/each.Rd b/man/each.Rd
index 6568e6b..3f23e4c 100644
--- a/man/each.Rd
+++ b/man/each.Rd
@@ -1,17 +1,18 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{each}
 \alias{each}
 \title{Aggregate multiple functions into a single function.}
 \usage{
-  each(...)
+each(...)
 }
 \arguments{
   \item{...}{functions to combine. each function should
   produce a single number as output}
 }
 \description{
-  Combine multiple functions into a single function
-  returning a named vector of outputs. Note: you cannot
-  supply additional parameters for the summary functions
+Combine multiple functions into a single function returning a named vector
+of outputs.
+Note: you cannot supply additional parameters for the summary functions
 }
 \examples{
 # Call min() and max() on the vector 1:10
@@ -28,8 +29,7 @@ each(c(min, max))(1:10)
 each(length, mean, var)(rnorm(100))
 }
 \seealso{
-  \code{\link{summarise}} for applying summary functions to
-  data
+\code{\link{summarise}} for applying summary functions to data
 }
 \keyword{manip}
 
diff --git a/man/empty.Rd b/man/empty.Rd
index 8a33127..0bcb618 100644
--- a/man/empty.Rd
+++ b/man/empty.Rd
@@ -1,14 +1,15 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{empty}
 \alias{empty}
 \title{Check if a data frame is empty.}
 \usage{
-  empty(df)
+empty(df)
 }
 \arguments{
   \item{df}{data frame to check}
 }
 \description{
-  Empty if it's null or it has 0 rows or columns
+Empty if it's null or it has 0 rows or columns
 }
 \keyword{internal}
 
diff --git a/man/eval.quoted.Rd b/man/eval.quoted.Rd
index c31c228..45b8dee 100644
--- a/man/eval.quoted.Rd
+++ b/man/eval.quoted.Rd
@@ -1,9 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{eval.quoted}
 \alias{eval.quoted}
 \title{Evaluate a quoted list of variables.}
 \usage{
-  eval.quoted(exprs, envir = NULL, enclos = NULL,
-    try = FALSE)
+eval.quoted(exprs, envir = NULL, enclos = NULL, try = FALSE)
 }
 \arguments{
   \item{expr}{quoted object to evalution}
@@ -12,10 +12,10 @@
   unsuccesful}
 }
 \value{
-  a list
+a list
 }
 \description{
-  Evaluates quoted variables in specified environment
+Evaluates quoted variables in specified environment
 }
 \keyword{internal}
 
diff --git a/man/failwith.Rd b/man/failwith.Rd
index f129b3a..3a61f07 100644
--- a/man/failwith.Rd
+++ b/man/failwith.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{failwith}
 \alias{failwith}
 \title{Fail with specified value.}
 \usage{
-  failwith(default = NULL, f, quiet = FALSE)
+failwith(default = NULL, f, quiet = FALSE)
 }
 \arguments{
   \item{default}{default value}
@@ -12,11 +13,11 @@
   \item{quiet}{all error messages be suppressed?}
 }
 \value{
-  a function
+a function
 }
 \description{
-  Modify a function so that it returns a default value when
-  there is an error.
+Modify a function so that it returns a default value when there is an
+error.
 }
 \examples{
 f <- function(x) if (x == 1) stop("Error!") else 1
@@ -30,7 +31,7 @@ safef(1)
 safef(2)
 }
 \seealso{
-  \code{\link{try_default}}
+\code{\link{try_default}}
 }
 \keyword{debugging}
 
diff --git a/man/get-split.Rd b/man/get-split.Rd
index b38a526..35f394b 100644
--- a/man/get-split.Rd
+++ b/man/get-split.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{[.split}
 \alias{[.split}
 \title{Subset splits.}
 \usage{
-  \method{[}{split} (x, i, ...)
+\method{[}{split}(x, i, ...)
 }
 \arguments{
   \item{x}{split object}
@@ -12,7 +13,7 @@
   \item{...}{unused}
 }
 \description{
-  Subset splits, ensuring that labels keep matching
+Subset splits, ensuring that labels keep matching
 }
 \keyword{internal}
 
diff --git a/man/here.Rd b/man/here.Rd
index d94d11a..a13d72a 100644
--- a/man/here.Rd
+++ b/man/here.Rd
@@ -1,17 +1,17 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{here}
 \alias{here}
 \title{Capture current evaluation context.}
 \usage{
-  here(f)
+here(f)
 }
 \arguments{
   \item{f}{a function that does non-standard evaluation}
 }
 \description{
-  This function captures the current context, making it
-  easier to use \code{**ply} with functions that do special
-  evaluation and need access to the environment where ddply
-  was called from.
+This function captures the current context, making it easier
+to use \code{**ply} with functions that do special evaluation and
+need access to the environment where ddply was called from.
 }
 \examples{
 df <- data.frame(a = rep(c("a","b"), each = 10), b = 1:20)
@@ -28,6 +28,6 @@ f2("name:")
 # Works :)
 }
 \author{
-  Peter Meilstrup, \url{https://github.com/crowding}
+Peter Meilstrup, \url{https://github.com/crowding}
 }
 
diff --git a/man/id.Rd b/man/id.Rd
index 9d46d8b..c9e63bd 100644
--- a/man/id.Rd
+++ b/man/id.Rd
@@ -1,9 +1,10 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{id}
 \alias{id}
 \alias{ninteraction}
 \title{Compute a unique numeric id for each unique row in a data frame.}
 \usage{
-  id(.variables, drop = FALSE)
+id(.variables, drop = FALSE)
 }
 \arguments{
   \item{.variables}{list of variables}
@@ -11,17 +12,19 @@
   \item{drop}{drop unusued factor levels?}
 }
 \value{
-  a numeric vector with attribute n, giving total number of
+a numeric vector with attribute n, giving total number of
   possibilities
 }
 \description{
-  Properties: \itemize{ \item \code{order(id)} is
-  equivalent to \code{do.call(order, df)} \item rows
-  containing the same data have the same value \item if
-  \code{drop = FALSE} then room for all possibilites }
+Properties:
+\itemize{
+  \item \code{order(id)} is equivalent to \code{do.call(order, df)}
+  \item rows containing the same data have the same value
+  \item if \code{drop = FALSE} then room for all possibilites
+}
 }
 \seealso{
-  \code{\link{id_var}}
+\code{\link{id_var}}
 }
 \keyword{internal}
 
diff --git a/man/id_var.Rd b/man/id_var.Rd
index 9fef8db..575feea 100644
--- a/man/id_var.Rd
+++ b/man/id_var.Rd
@@ -1,11 +1,12 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{id_var}
 \alias{id_var}
 \title{Numeric id for a vector.}
 \usage{
-  id_var(x, drop = FALSE)
+id_var(x, drop = FALSE)
 }
 \description{
-  Numeric id for a vector.
+Numeric id for a vector.
 }
 \keyword{internal}
 
diff --git a/man/idata.frame.Rd b/man/idata.frame.Rd
index 61b7372..b44b6f4 100644
--- a/man/idata.frame.Rd
+++ b/man/idata.frame.Rd
@@ -1,26 +1,25 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{idata.frame}
 \alias{idata.frame}
 \title{Construct an immutable data frame.}
 \usage{
-  idata.frame(df)
+idata.frame(df)
 }
 \arguments{
   \item{df}{a data frame}
 }
 \value{
-  an immutable data frame
+an immutable data frame
 }
 \description{
-  An immutable data frame works like an ordinary data
-  frame, except that when you subset it, it returns a
-  reference to the original data frame, not a a copy. This
-  makes subsetting substantially faster and has a big
-  impact when you are working with large datasets with many
-  groups.
+An immutable data frame works like an ordinary data frame, except that when
+you subset it, it returns a reference to the original data frame, not a
+a copy. This makes subsetting substantially faster and has a big impact
+when you are working with large datasets with many groups.
 }
 \details{
-  This method is still a little experimental, so please let
-  me know if you run into any problems.
+This method is still a little experimental, so please let me know if you
+run into any problems.
 }
 \examples{
 system.time(dlply(baseball, "id", nrow))
diff --git a/man/indexed_array.Rd b/man/indexed_array.Rd
index 1a34b5a..94524af 100644
--- a/man/indexed_array.Rd
+++ b/man/indexed_array.Rd
@@ -1,3 +1,4 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{indexed_array}
 \alias{[[.indexed_array}
 \alias{indexed_array}
@@ -5,7 +6,7 @@
 \alias{names.indexed_array}
 \title{An indexed array.}
 \usage{
-  indexed_array(env, index)
+indexed_array(env, index)
 }
 \arguments{
   \item{env}{environment containing data frame}
@@ -13,8 +14,8 @@
   \item{index}{list of indices}
 }
 \description{
-  Create a indexed array, a space efficient way of indexing
-  into a large array.
+Create a indexed array, a space efficient way of indexing into a large
+array.
 }
 \keyword{internal}
 
diff --git a/man/indexed_df.Rd b/man/indexed_df.Rd
index d1458a4..974d9ef 100644
--- a/man/indexed_df.Rd
+++ b/man/indexed_df.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{indexed_df}
 \alias{indexed_df}
 \title{An indexed data frame.}
 \usage{
-  indexed_df(data, index, vars)
+indexed_df(data, index, vars)
 }
 \arguments{
   \item{env}{environment containing data frame}
@@ -13,8 +14,7 @@
   for subsetting}
 }
 \description{
-  Create a indexed list, a space efficient way of indexing
-  into a large data frame
+Create a indexed list, a space efficient way of indexing into a large data frame
 }
 \keyword{internal}
 
diff --git a/man/is.discrete.Rd b/man/is.discrete.Rd
index fbca182..8f76914 100644
--- a/man/is.discrete.Rd
+++ b/man/is.discrete.Rd
@@ -1,14 +1,15 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{is.discrete}
 \alias{is.discrete}
 \title{Determine if a vector is discrete.}
 \usage{
-  is.discrete(x)
+is.discrete(x)
 }
 \arguments{
   \item{x}{vector to test}
 }
 \description{
-  A discrete vector is a factor or a character vector
+A discrete vector is a factor or a character vector
 }
 \examples{
 is.discrete(1:10)
diff --git a/man/is.formula.Rd b/man/is.formula.Rd
index 0f9def2..38c507e 100644
--- a/man/is.formula.Rd
+++ b/man/is.formula.Rd
@@ -1,12 +1,14 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{is.formula}
 \alias{is.formula}
 \title{Is a formula?
 Checks if argument is a formula}
 \usage{
-  is.formula(x)
+is.formula(x)
 }
 \description{
-  Is a formula? Checks if argument is a formula
+Is a formula?
+Checks if argument is a formula
 }
 \keyword{internal}
 
diff --git a/man/isplit2.Rd b/man/isplit2.Rd
index 00aa9ca..8af982b 100644
--- a/man/isplit2.Rd
+++ b/man/isplit2.Rd
@@ -1,11 +1,12 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{isplit2}
 \alias{isplit2}
 \title{Split iterator that returns values, not indices.}
 \usage{
-  isplit2(x, f, drop = FALSE, ...)
+isplit2(x, f, drop = FALSE, ...)
 }
 \description{
-  Split iterator that returns values, not indices.
+Split iterator that returns values, not indices.
 }
 \keyword{internal}
 
diff --git a/man/join.Rd b/man/join.Rd
index dd9ec75..c010919 100644
--- a/man/join.Rd
+++ b/man/join.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{join}
 \alias{join}
 \title{Join two data frames together.}
 \usage{
-  join(x, y, by = NULL, type = "left", match = "all")
+join(x, y, by = NULL, type = "left", match = "all")
 }
 \arguments{
   \item{x}{data frame}
@@ -22,29 +23,28 @@
   significantly faster.}
 }
 \description{
-  Join, like merge, is designed for the types of problems
-  where you would use a sql join.
+Join, like merge, is designed for the types of problems
+where you would use a sql join.
 }
 \details{
-  The four join types return:
-
-  \itemize{ \item \code{inner}: only rows with matching
-  keys in both x and y \item \code{left}: all rows in x,
-  adding matching columns from y \item \code{right}: all
-  rows in y, adding matching columns from x \item
-  \code{full}: all rows in x with matching columns in y,
-  then the rows of y that don't match x. }
-
-  Note that from plyr 1.5, \code{join} will (by default)
-  return all matches, not just the first match, as it did
-  previously.
-
-  Unlike merge, preserves the order of x no matter what
-  join type is used. If needed, rows from y will be added
-  to the bottom.  Join is often faster than merge, although
-  it is somewhat less featureful - it currently offers no
-  way to rename output or merge on different variables in
-  the x and y data frames.
+The four join types return:
+
+\itemize{
+ \item \code{inner}:  only rows with matching keys in both x and y
+ \item \code{left}:   all rows in x, adding matching columns from y
+ \item \code{right}:  all rows in y, adding matching columns from x
+ \item \code{full}:   all rows in x with matching columns in y, then the
+   rows of y that don't match x.
+}
+
+Note that from plyr 1.5, \code{join} will (by default) return all matches,
+not just the first match, as it did previously.
+
+Unlike merge, preserves the order of x no matter what join type is used.
+If needed, rows from y will be added to the bottom.  Join is often faster
+than merge, although it is somewhat less featureful - it currently offers
+no way to rename output or merge on different variables in the x and y
+data frames.
 }
 \examples{
 first <- ddply(baseball, "id", summarise, first = min(year))
diff --git a/man/join.keys.Rd b/man/join.keys.Rd
index fb5450e..00680d8 100644
--- a/man/join.keys.Rd
+++ b/man/join.keys.Rd
@@ -1,9 +1,10 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{join.keys}
 \alias{join.keys}
 \title{Join keys.
 Given two data frames, create a unique key for each row.}
 \usage{
-  join.keys(x, y, by)
+join.keys(x, y, by)
 }
 \arguments{
   \item{x}{data frame}
@@ -13,8 +14,8 @@ Given two data frames, create a unique key for each row.}
   \item{by}{character vector of variable names to join by}
 }
 \description{
-  Join keys. Given two data frames, create a unique key for
-  each row.
+Join keys.
+Given two data frames, create a unique key for each row.
 }
 \keyword{internal}
 
diff --git a/man/join_all.Rd b/man/join_all.Rd
index 203ad69..5b4d0d0 100644
--- a/man/join_all.Rd
+++ b/man/join_all.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{join_all}
 \alias{join_all}
 \title{Recursively join a list of data frames.}
 \usage{
-  join_all(dfs, by = NULL, type = "left", match = "all")
+join_all(dfs, by = NULL, type = "left", match = "all")
 }
 \arguments{
   \item{dfs}{A list of data frames.}
@@ -20,7 +21,7 @@
   significantly faster.}
 }
 \description{
-  Recursively join a list of data frames.
+Recursively join a list of data frames.
 }
 \examples{
 dfs <- list(
diff --git a/man/l_ply.Rd b/man/l_ply.Rd
index 0f58181..f41da5b 100644
--- a/man/l_ply.Rd
+++ b/man/l_ply.Rd
@@ -1,10 +1,10 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{l_ply}
 \alias{l_ply}
 \title{Split list, apply function, and discard results.}
 \usage{
-  l_ply(.data, .fun = NULL, ..., .progress = "none",
-    .inform = FALSE, .print = FALSE, .parallel = FALSE,
-    .paropts = NULL)
+l_ply(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE,
+  .print = FALSE, .parallel = FALSE, .paropts = NULL)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -35,11 +35,10 @@
   \code{FALSE})}
 }
 \value{
-  Nothing
+Nothing
 }
 \description{
-  For each element of a list, apply function and discard
-  results
+For each element of a list, apply function and discard results
 }
 \section{Input}{
   This function splits lists by elements.
@@ -51,16 +50,16 @@
   displaying plots or saving output.
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  Other list input: \code{\link{laply}},
-  \code{\link{ldply}}, \code{\link{llply}}
+Other list input: \code{\link{laply}}; \code{\link{ldply}};
+  \code{\link{llply}}
 
-  Other no output: \code{\link{a_ply}},
-  \code{\link{d_ply}}, \code{\link{m_ply}}
+Other no output: \code{\link{a_ply}}; \code{\link{d_ply}};
+  \code{\link{m_ply}}
 }
 \keyword{manip}
 
diff --git a/man/laply.Rd b/man/laply.Rd
index 2359be1..dfaaa76 100644
--- a/man/laply.Rd
+++ b/man/laply.Rd
@@ -1,10 +1,10 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{laply}
 \alias{laply}
 \title{Split list, apply function, and return results in an array.}
 \usage{
-  laply(.data, .fun = NULL, ..., .progress = "none",
-    .inform = FALSE, .drop = TRUE, .parallel = FALSE,
-    .paropts = NULL)
+laply(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE,
+  .drop = TRUE, .parallel = FALSE, .paropts = NULL)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -36,19 +36,19 @@
   \code{TRUE}}
 }
 \value{
-  if results are atomic with same type and dimensionality,
-  a vector, matrix or array; otherwise, a list-array (a
-  list with dimensions)
+if results are atomic with same type and dimensionality, a
+  vector, matrix or array; otherwise, a list-array (a list with
+  dimensions)
 }
 \description{
-  For each element of a list, apply function then combine
-  results into an array.
+For each element of a list, apply function then combine results into an
+array.
 }
 \details{
-  \code{laply} is similar in spirit to \code{\link{sapply}}
-  except that it will always return an array, and the
-  output is transposed with respect \code{sapply} - each
-  element of the list corresponds to a row, not a column.
+\code{laply} is similar in spirit to \code{\link{sapply}} except
+that it will always return an array, and the output is transposed with
+respect \code{sapply} - each element of the list corresponds to a row,
+not a column.
 }
 \section{Input}{
   This function splits lists by elements.
@@ -69,16 +69,16 @@ laply(seq_len(10), rep, times = 4)
 laply(seq_len(10), matrix, nrow = 2, ncol = 2)
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  Other array output: \code{\link{aaply}},
-  \code{\link{daply}}, \code{\link{maply}}
+Other array output: \code{\link{aaply}};
+  \code{\link{daply}}; \code{\link{maply}}
 
-  Other list input: \code{\link{l_ply}},
-  \code{\link{ldply}}, \code{\link{llply}}
+Other list input: \code{\link{l_ply}}; \code{\link{ldply}};
+  \code{\link{llply}}
 }
 \keyword{manip}
 
diff --git a/man/ldply.Rd b/man/ldply.Rd
index 8fda85f..aca7856 100644
--- a/man/ldply.Rd
+++ b/man/ldply.Rd
@@ -1,9 +1,10 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{ldply}
 \alias{ldply}
 \title{Split list, apply function, and return results in a data frame.}
 \usage{
-  ldply(.data, .fun = NULL, ..., .progress = "none",
-    .inform = FALSE, .parallel = FALSE, .paropts = NULL)
+ldply(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE,
+  .parallel = FALSE, .paropts = NULL, .id = NA)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -29,13 +30,20 @@
   slows processing speed, but is very useful for debugging}
 
   \item{.data}{list to be processed}
+
+  \item{.id}{name of the index column (used if \code{.data}
+  is a named list).  Pass \code{NULL} to avoid creation of
+  the index column. For compatibility, omit this argument
+  or pass \code{NA} to avoid converting the index column to
+  a factor; in this case, \code{".id"} is used as colum
+  name.}
 }
 \value{
-  A data frame, as described in the output section.
+A data frame, as described in the output section.
 }
 \description{
-  For each element of a list, apply function then combine
-  results into a data frame.
+For each element of a list, apply function then combine results into a data
+frame.
 }
 \section{Input}{
   This function splits lists by elements.
@@ -54,16 +62,16 @@
   (\code{data.frame()}).
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  Other data frame output: \code{\link{adply}},
-  \code{\link{ddply}}, \code{\link{mdply}}
+Other data frame output: \code{\link{adply}};
+  \code{\link{ddply}}; \code{\link{mdply}}
 
-  Other list input: \code{\link{l_ply}},
-  \code{\link{laply}}, \code{\link{llply}}
+Other list input: \code{\link{l_ply}}; \code{\link{laply}};
+  \code{\link{llply}}
 }
 \keyword{manip}
 
diff --git a/man/liply.Rd b/man/liply.Rd
index b03dbd4..c35fc8a 100644
--- a/man/liply.Rd
+++ b/man/liply.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{liply}
 \alias{liply}
 \title{Experimental iterator based version of llply.}
 \usage{
-  liply(.iterator, .fun = NULL, ...)
+liply(.iterator, .fun = NULL, ...)
 }
 \arguments{
   \item{.iterator}{iterator object}
@@ -12,12 +13,11 @@
   \item{...}{other arguments passed on to \code{.fun}}
 }
 \description{
-  Because iterators do not have known length, \code{liply}
-  starts by allocating an output list of length 50, and
-  then doubles that length whenever it runs out of space.
-  This gives O(n ln n) performance rather than the O(n ^ 2)
-  performance from the naive strategy of growing the list
-  each time.
+Because iterators do not have known length, \code{liply} starts by
+allocating an output list of length 50, and then doubles that length
+whenever it runs out of space.  This gives O(n ln n) performance rather
+than the O(n ^ 2) performance from the naive strategy of growing the list
+each time.
 }
 \examples{
 if(require("iterators")) {
diff --git a/man/list_to_array.Rd b/man/list_to_array.Rd
index 1904f27..42689ae 100644
--- a/man/list_to_array.Rd
+++ b/man/list_to_array.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{list_to_array}
 \alias{list_to_array}
 \title{List to array.}
 \usage{
-  list_to_array(res, labels = NULL, .drop = FALSE)
+list_to_array(res, labels = NULL, .drop = FALSE)
 }
 \arguments{
   \item{res}{list of input data}
@@ -14,11 +15,10 @@
   preserved (FALSE)}
 }
 \description{
-  Reduce/simplify a list of homogenous objects to an array
+Reduce/simplify a list of homogenous objects to an array
 }
 \seealso{
-  Other list simplification functions:
-  \code{\link{list_to_dataframe}},
+Other list simplification functions: \code{\link{list_to_dataframe}};
   \code{\link{list_to_vector}}
 }
 \keyword{internal}
diff --git a/man/list_to_dataframe.Rd b/man/list_to_dataframe.Rd
index 59ef6d5..d35ed9d 100644
--- a/man/list_to_dataframe.Rd
+++ b/man/list_to_dataframe.Rd
@@ -1,23 +1,28 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{list_to_dataframe}
 \alias{list_to_dataframe}
 \title{List to data frame.}
 \usage{
-  list_to_dataframe(res, labels = NULL)
+list_to_dataframe(res, labels = NULL, id_name = NULL,
+  id_as_factor = FALSE)
 }
 \arguments{
   \item{res}{list of input data}
 
   \item{labels}{a data frame of labels, one row for each
   element of res}
+
+  \item{idname}{the name of the index column, \code{NULL}
+  for no index column}
 }
 \description{
-  Reduce/simplify a list of homogenous objects to a data
-  frame. All \code{NULL} entries are removed. Remaining
-  entries must be all atomic or all data frames.
+Reduce/simplify a list of homogenous objects to a data frame. All
+\code{NULL} entries are removed. Remaining entries must be all atomic
+or all data frames.
 }
 \seealso{
-  Other list simplification functions:
-  \code{\link{list_to_array}}, \code{\link{list_to_vector}}
+Other list simplification functions: \code{\link{list_to_array}};
+  \code{\link{list_to_vector}}
 }
 \keyword{internal}
 
diff --git a/man/list_to_vector.Rd b/man/list_to_vector.Rd
index 6456d91..9a2e3e3 100644
--- a/man/list_to_vector.Rd
+++ b/man/list_to_vector.Rd
@@ -1,18 +1,18 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{list_to_vector}
 \alias{list_to_vector}
 \title{List to vector.}
 \usage{
-  list_to_vector(res)
+list_to_vector(res)
 }
 \arguments{
   \item{res}{list of input data}
 }
 \description{
-  Reduce/simplify a list of homogenous objects to a vector
+Reduce/simplify a list of homogenous objects to a vector
 }
 \seealso{
-  Other list simplification functions:
-  \code{\link{list_to_array}},
+Other list simplification functions: \code{\link{list_to_array}};
   \code{\link{list_to_dataframe}}
 }
 \keyword{internal}
diff --git a/man/llply.Rd b/man/llply.Rd
index 9752fc9..907d9fe 100644
--- a/man/llply.Rd
+++ b/man/llply.Rd
@@ -1,9 +1,10 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{llply}
 \alias{llply}
 \title{Split list, apply function, and return results in a list.}
 \usage{
-  llply(.data, .fun = NULL, ..., .progress = "none",
-    .inform = FALSE, .parallel = FALSE, .paropts = NULL)
+llply(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE,
+  .parallel = FALSE, .paropts = NULL)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -31,16 +32,14 @@
   \item{.data}{list to be processed}
 }
 \value{
-  list of results
+list of results
 }
 \description{
-  For each element of a list, apply function, keeping
-  results as a list.
+For each element of a list, apply function, keeping results as a list.
 }
 \details{
-  \code{llply} is equivalent to \code{\link{lapply}} except
-  that it will preserve labels and can display a progress
-  bar.
+\code{llply} is equivalent to \code{\link{lapply}} except that it will
+preserve labels and can display a progress bar.
 }
 \section{Input}{
   This function splits lists by elements.
@@ -60,16 +59,16 @@ llply(x, mean)
 llply(x, quantile, probs = 1:3/4)
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  Other list input: \code{\link{l_ply}},
-  \code{\link{laply}}, \code{\link{ldply}}
+Other list input: \code{\link{l_ply}}; \code{\link{laply}};
+  \code{\link{ldply}}
 
-  Other list output: \code{\link{alply}},
-  \code{\link{dlply}}, \code{\link{mlply}}
+Other list output: \code{\link{alply}};
+  \code{\link{dlply}}; \code{\link{mlply}}
 }
 \keyword{manip}
 
diff --git a/man/loop_apply.Rd b/man/loop_apply.Rd
index 81b0157..1251467 100644
--- a/man/loop_apply.Rd
+++ b/man/loop_apply.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{loop_apply}
 \alias{loop_apply}
 \title{Loop apply}
 \usage{
-  loop_apply(n, f, env = parent.frame())
+loop_apply(n, f)
 }
 \arguments{
   \item{n}{length of sequence}
@@ -12,8 +13,8 @@
   \item{env}{environment in which to evaluate function}
 }
 \description{
-  An optimised version of lapply for the special case of
-  operating on \code{seq_len(n)}
+An optimised version of lapply for the special case of operating on
+\code{seq_len(n)}
 }
 \keyword{internal}
 \keyword{manip}
diff --git a/man/m_ply.Rd b/man/m_ply.Rd
index 08bd322..c6f2df2 100644
--- a/man/m_ply.Rd
+++ b/man/m_ply.Rd
@@ -1,10 +1,10 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{m_ply}
 \alias{m_ply}
 \title{Call function with arguments in array or data frame, discarding results.}
 \usage{
-  m_ply(.data, .fun = NULL, ..., .expand = TRUE,
-    .progress = "none", .inform = FALSE, .print = FALSE,
-    .parallel = FALSE, .paropts = NULL)
+m_ply(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none",
+  .inform = FALSE, .print = FALSE, .parallel = FALSE, .paropts = NULL)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -40,19 +40,17 @@
   \code{FALSE})}
 }
 \value{
-  Nothing
+Nothing
 }
 \description{
-  Call a multi-argument function with values taken from
-  columns of an data frame or array, and discard results
-  into a list.
+Call a multi-argument function with values taken from columns of an
+data frame or array, and discard results into a list.
 }
 \details{
-  The \code{m*ply} functions are the \code{plyr} version of
-  \code{mapply}, specialised according to the type of
-  output they produce.  These functions are just a
-  convenient wrapper around \code{a*ply} with \code{margins
-  = 1} and \code{.fun} wrapped in \code{\link{splat}}.
+The \code{m*ply} functions are the \code{plyr} version of \code{mapply},
+specialised according to the type of output they produce.  These functions
+are just a convenient wrapper around \code{a*ply} with \code{margins = 1}
+and \code{.fun} wrapped in \code{\link{splat}}.
 }
 \section{Input}{
   Call a multi-argument function with values taken from
@@ -65,16 +63,16 @@
   displaying plots or saving output.
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  Other multiple arguments input: \code{\link{maply}},
-  \code{\link{mdply}}, \code{\link{mlply}}
+Other multiple arguments input: \code{\link{maply}};
+  \code{\link{mdply}}; \code{\link{mlply}}
 
-  Other no output: \code{\link{a_ply}},
-  \code{\link{d_ply}}, \code{\link{l_ply}}
+Other no output: \code{\link{a_ply}}; \code{\link{d_ply}};
+  \code{\link{l_ply}}
 }
 \keyword{manip}
 
diff --git a/man/maply.Rd b/man/maply.Rd
index c613db4..d67b2b9 100644
--- a/man/maply.Rd
+++ b/man/maply.Rd
@@ -1,10 +1,10 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{maply}
 \alias{maply}
 \title{Call function with arguments in array or data frame, returning an array.}
 \usage{
-  maply(.data, .fun = NULL, ..., .expand = TRUE,
-    .progress = "none", .inform = FALSE, .drop = TRUE,
-    .parallel = FALSE, .paropts = NULL)
+maply(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none",
+  .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -41,21 +41,19 @@
   \code{TRUE}}
 }
 \value{
-  if results are atomic with same type and dimensionality,
-  a vector, matrix or array; otherwise, a list-array (a
-  list with dimensions)
+if results are atomic with same type and dimensionality, a
+  vector, matrix or array; otherwise, a list-array (a list with
+  dimensions)
 }
 \description{
-  Call a multi-argument function with values taken from
-  columns of an data frame or array, and combine results
-  into an array
+Call a multi-argument function with values taken from columns of an
+data frame or array, and combine results into an array
 }
 \details{
-  The \code{m*ply} functions are the \code{plyr} version of
-  \code{mapply}, specialised according to the type of
-  output they produce.  These functions are just a
-  convenient wrapper around \code{a*ply} with \code{margins
-  = 1} and \code{.fun} wrapped in \code{\link{splat}}.
+The \code{m*ply} functions are the \code{plyr} version of \code{mapply},
+specialised according to the type of output they produce.  These functions
+are just a convenient wrapper around \code{a*ply} with \code{margins = 1}
+and \code{.fun} wrapped in \code{\link{splat}}.
 }
 \section{Input}{
   Call a multi-argument function with values taken from
@@ -72,16 +70,16 @@ maply(expand.grid(mean = 1:5, sd = 1:5), rnorm, n = 5)
 maply(cbind(1:5, 1:5), rnorm, n = 5)
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  Other array output: \code{\link{aaply}},
-  \code{\link{daply}}, \code{\link{laply}}
+Other array output: \code{\link{aaply}};
+  \code{\link{daply}}; \code{\link{laply}}
 
-  Other multiple arguments input: \code{\link{m_ply}},
-  \code{\link{mdply}}, \code{\link{mlply}}
+Other multiple arguments input: \code{\link{m_ply}};
+  \code{\link{mdply}}; \code{\link{mlply}}
 }
 \keyword{manip}
 
diff --git a/man/mapvalues.Rd b/man/mapvalues.Rd
index 9993d2d..f058b72 100644
--- a/man/mapvalues.Rd
+++ b/man/mapvalues.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{mapvalues}
 \alias{mapvalues}
 \title{Replace specified values with new values, in a vector or factor.}
 \usage{
-  mapvalues(x, from, to, warn_missing = TRUE)
+mapvalues(x, from, to, warn_missing = TRUE)
 }
 \arguments{
   \item{x}{the factor or vector to modify}
@@ -15,19 +16,17 @@
   values are not actually present in \code{x}}
 }
 \description{
-  Item in \code{x} that match items \code{from} will be
-  replaced by items in \code{to}, matched by position. For
-  example, items in \code{x} that match the first element
-  in \code{from} will be replaced by the first element of
-  \code{to}.
+Item in \code{x} that match items \code{from} will be replaced by
+items in \code{to}, matched by position. For example, items in \code{x} that
+match the first element in \code{from} will be replaced by the first
+element of \code{to}.
 }
 \details{
-  If \code{x} is a factor, the matching levels of the
-  factor will be replaced with the new values.
+If \code{x} is a factor, the matching levels of the factor will be
+replaced with the new values.
 
-  The related \code{revalue} function works only on
-  character vectors and factors, but this function works on
-  vectors of any type and factors.
+The related \code{revalue} function works only on character vectors
+and factors, but this function works on vectors of any type and factors.
 }
 \examples{
 x <- c("a", "b", "c")
@@ -42,7 +41,7 @@ z <- c(1, 4, 5, 9)
 mapvalues(z, from = c(1, 5, 9), to = c(10, 50, 90))
 }
 \seealso{
-  \code{\link{revalue}} to do the same thing but with a
-  single named vector instead of two separate vectors.
+\code{\link{revalue}} to do the same thing but with a single
+  named vector instead of two separate vectors.
 }
 
diff --git a/man/match_df.Rd b/man/match_df.Rd
index 2dc5dd0..8051ad3 100644
--- a/man/match_df.Rd
+++ b/man/match_df.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{match_df}
 \alias{match_df}
 \title{Extract matching rows of a data frame.}
 \usage{
-  match_df(x, y, on = NULL)
+match_df(x, y, on = NULL)
 }
 \arguments{
   \item{x}{data frame to subset.}
@@ -13,24 +14,23 @@
   variables common to both data frames.}
 }
 \value{
-  a data frame
+a data frame
 }
 \description{
-  Match works in the same way as join, but instead of
-  return the combined dataset, it only returns the matching
-  rows from the first dataset. This is particularly useful
-  when you've summarised the data in some way and want to
-  subset the original data by a characteristic of the
-  subset.
+Match works in the same way as join, but instead of return the combined
+dataset, it only returns the matching rows from the first dataset. This is
+particularly useful when you've summarised the data in some way
+and want to subset the original data by a characteristic of the subset.
 }
 \details{
-  \code{match_df} shares the same semantics as
-  \code{\link{join}}, not \code{\link{match}}:
+\code{match_df} shares the same semantics as \code{\link{join}}, not
+\code{\link{match}}:
 
-  \itemize{ \item the match criterion is \code{==}, not
-  \code{\link{identical}}).  \item it doesn't work for
-  columns that are not atomic vectors \item if there are no
-  matches, the row will be omitted' }
+\itemize{
+  \item the match criterion is \code{==}, not \code{\link{identical}}).
+  \item it doesn't work for columns that are not atomic vectors
+  \item if there are no matches, the row will be omitted'
+}
 }
 \examples{
 # count the occurrences of each id in the baseball dataframe, then get the subset with a freq >25
@@ -46,8 +46,7 @@ bb_longterm <- match_df(baseball, longterm, on="id")
 bb_longterm[1:5,]
 }
 \seealso{
-  \code{\link{join}} to combine the columns from both x and
-  y and \code{\link{match}} for the base function selecting
-  matching items
+\code{\link{join}} to combine the columns from both x and y
+ and \code{\link{match}} for the base function selecting matching items
 }
 
diff --git a/man/mdply.Rd b/man/mdply.Rd
index 38ba31e..236837b 100644
--- a/man/mdply.Rd
+++ b/man/mdply.Rd
@@ -1,10 +1,10 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{mdply}
 \alias{mdply}
 \title{Call function with arguments in array or data frame, returning a data frame.}
 \usage{
-  mdply(.data, .fun = NULL, ..., .expand = TRUE,
-    .progress = "none", .inform = FALSE, .parallel = FALSE,
-    .paropts = NULL)
+mdply(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none",
+  .inform = FALSE, .parallel = FALSE, .paropts = NULL)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -37,19 +37,17 @@
   dimension for each variable.}
 }
 \value{
-  A data frame, as described in the output section.
+A data frame, as described in the output section.
 }
 \description{
-  Call a multi-argument function with values taken from
-  columns of an data frame or array, and combine results
-  into a data frame
+Call a multi-argument function with values taken from columns of an
+data frame or array, and combine results into a data frame
 }
 \details{
-  The \code{m*ply} functions are the \code{plyr} version of
-  \code{mapply}, specialised according to the type of
-  output they produce.  These functions are just a
-  convenient wrapper around \code{a*ply} with \code{margins
-  = 1} and \code{.fun} wrapped in \code{\link{splat}}.
+The \code{m*ply} functions are the \code{plyr} version of \code{mapply},
+specialised according to the type of output they produce.  These functions
+are just a convenient wrapper around \code{a*ply} with \code{margins = 1}
+and \code{.fun} wrapped in \code{\link{splat}}.
 }
 \section{Input}{
   Call a multi-argument function with values taken from
@@ -75,16 +73,16 @@ mdply(cbind(mean = 1:5, sd = 1:5), rnorm, n = 5)
 mdply(cbind(mean = 1:5, sd = 1:5), as.data.frame(rnorm), n = 5)
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  Other data frame output: \code{\link{adply}},
-  \code{\link{ddply}}, \code{\link{ldply}}
+Other data frame output: \code{\link{adply}};
+  \code{\link{ddply}}; \code{\link{ldply}}
 
-  Other multiple arguments input: \code{\link{m_ply}},
-  \code{\link{maply}}, \code{\link{mlply}}
+Other multiple arguments input: \code{\link{m_ply}};
+  \code{\link{maply}}; \code{\link{mlply}}
 }
 \keyword{manip}
 
diff --git a/man/mlply.Rd b/man/mlply.Rd
index f81148d..d037fdc 100644
--- a/man/mlply.Rd
+++ b/man/mlply.Rd
@@ -1,10 +1,10 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{mlply}
 \alias{mlply}
 \title{Call function with arguments in array or data frame, returning a list.}
 \usage{
-  mlply(.data, .fun = NULL, ..., .expand = TRUE,
-    .progress = "none", .inform = FALSE, .parallel = FALSE,
-    .paropts = NULL)
+mlply(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none",
+  .inform = FALSE, .parallel = FALSE, .paropts = NULL)
 }
 \arguments{
   \item{.fun}{function to apply to each piece}
@@ -37,19 +37,17 @@
   dimension for each variable.}
 }
 \value{
-  list of results
+list of results
 }
 \description{
-  Call a multi-argument function with values taken from
-  columns of an data frame or array, and combine results
-  into a list.
+Call a multi-argument function with values taken from columns of an
+data frame or array, and combine results into a list.
 }
 \details{
-  The \code{m*ply} functions are the \code{plyr} version of
-  \code{mapply}, specialised according to the type of
-  output they produce.  These functions are just a
-  convenient wrapper around \code{a*ply} with \code{margins
-  = 1} and \code{.fun} wrapped in \code{\link{splat}}.
+The \code{m*ply} functions are the \code{plyr} version of \code{mapply},
+specialised according to the type of output they produce.  These functions
+are just a convenient wrapper around \code{a*ply} with \code{margins = 1}
+and \code{.fun} wrapped in \code{\link{splat}}.
 }
 \section{Input}{
   Call a multi-argument function with values taken from
@@ -69,16 +67,16 @@ mlply(cbind(1:4, length = 4:1), seq)
 mlply(cbind(1:4, by = 4:1), seq, to = 20)
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy
+  for Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \seealso{
-  Other list output: \code{\link{alply}},
-  \code{\link{dlply}}, \code{\link{llply}}
+Other list output: \code{\link{alply}};
+  \code{\link{dlply}}; \code{\link{llply}}
 
-  Other multiple arguments input: \code{\link{m_ply}},
-  \code{\link{maply}}, \code{\link{mdply}}
+Other multiple arguments input: \code{\link{m_ply}};
+  \code{\link{maply}}; \code{\link{mdply}}
 }
 \keyword{manip}
 
diff --git a/man/mutate.Rd b/man/mutate.Rd
index 5e9e789..3a21084 100644
--- a/man/mutate.Rd
+++ b/man/mutate.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{mutate}
 \alias{mutate}
 \title{Mutate a data frame by adding new or replacing existing columns.}
 \usage{
-  mutate(.data, ...)
+mutate(.data, ...)
 }
 \arguments{
   \item{.data}{the data frame to transform}
@@ -11,15 +12,14 @@
   columns.}
 }
 \description{
-  This function is very similar to \code{\link{transform}}
-  but it executes the transformations iteratively so that
-  later transformations can use the columns created by
-  earlier transformations.  Like transform, unnamed
-  components are silently dropped.
+This function is very similar to \code{\link{transform}} but it executes
+the transformations iteratively so that later transformations can use the
+columns created by earlier transformations.  Like transform, unnamed
+components are silently dropped.
 }
 \details{
-  Mutate seems to be considerably faster than transform for
-  large data frames.
+Mutate seems to be considerably faster than transform for large data
+frames.
 }
 \examples{
 # Examples from transform
@@ -34,9 +34,8 @@ system.time(transform(baseball, avg_ab = ab / g))
 system.time(mutate(baseball, avg_ab = ab / g))
 }
 \seealso{
-  \code{\link{subset}}, \code{\link{summarise}},
-  \code{\link{arrange}}.  For another somewhat different
-  approach to solving the same problem, see
-  \code{\link{within}}.
+\code{\link{subset}}, \code{\link{summarise}},
+  \code{\link{arrange}}.  For another somewhat different approach to
+  solving the same problem, see \code{\link{within}}.
 }
 
diff --git a/man/name_rows.Rd b/man/name_rows.Rd
index c46c5f7..e4775c7 100644
--- a/man/name_rows.Rd
+++ b/man/name_rows.Rd
@@ -1,20 +1,19 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{name_rows}
 \alias{name_rows}
 \title{Toggle row names between explicit and implicit.}
 \usage{
-  name_rows(df)
+name_rows(df)
 }
 \arguments{
   \item{df}{a data.frame, with either \code{rownames}, or a
   column called \code{.rownames}.}
 }
 \description{
-  Plyr functions ignore row names, so this function
-  provides a way to preserve them by converting them to an
-  explicit column in the data frame.  After the plyr
-  operation, you can then apply \code{name_rows} again to
-  convert back from the explicit column to the implicit
-  \code{rownames}.
+Plyr functions ignore row names, so this function provides a way to preserve
+them by converting them to an explicit column in the data frame.  After the
+plyr operation, you can then apply \code{name_rows} again to convert back
+from the explicit column to the implicit \code{rownames}.
 }
 \examples{
 name_rows(mtcars)
diff --git a/man/names.quoted.Rd b/man/names.quoted.Rd
index 8c6141e..a67345f 100644
--- a/man/names.quoted.Rd
+++ b/man/names.quoted.Rd
@@ -1,14 +1,14 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{names.quoted}
 \alias{names.quoted}
 \title{Compute names of quoted variables.}
 \usage{
-  \method{names}{quoted} (x)
+\method{names}{quoted}(x)
 }
 \description{
-  Figure out names of quoted variables, using specified
-  names if they exist, otherwise converting the values to
-  character strings.  This may create variable names that
-  can only be accessed using \code{``}.
+Figure out names of quoted variables, using specified names if they exist,
+otherwise converting the values to character strings.  This may create
+variable names that can only be accessed using \code{``}.
 }
 \keyword{internal}
 
diff --git a/man/nunique.Rd b/man/nunique.Rd
index af90f1f..ecc02ab 100644
--- a/man/nunique.Rd
+++ b/man/nunique.Rd
@@ -1,15 +1,15 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{nunique}
 \alias{nunique}
 \title{Number of unique values.}
 \usage{
-  nunique(x)
+nunique(x)
 }
 \arguments{
   \item{x}{vector}
 }
 \description{
-  Calculate number of unique values of a variable as
-  efficiently as possible.
+Calculate number of unique values of a variable as efficiently as possible.
 }
 \keyword{internal}
 
diff --git a/man/ozone.Rd b/man/ozone.Rd
index c0e2b4e..84397af 100644
--- a/man/ozone.Rd
+++ b/man/ozone.Rd
@@ -1,17 +1,19 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \docType{data}
 \name{ozone}
 \alias{ozone}
 \title{Monthly ozone measurements over Central America.}
 \format{A 24 x 24 x 72 numeric array}
+\usage{
+ozone
+}
 \description{
-  This data set is a subset of the data from the 2006 ASA
-  Data expo challenge,
-  \url{http://stat-computing.org/dataexpo/2006/}. The data
-  are monthly ozone averages on a very coarse 24 by 24 grid
-  covering Central America, from Jan 1995 to Dec 2000. The
-  data is stored in a 3d area with the first two dimensions
-  representing latitude and longitude, and the third
-  representing time.
+This data set is a subset of the data from the 2006 ASA Data expo
+challenge, \url{http://stat-computing.org/dataexpo/2006/}. The data are
+monthly ozone averages on a very coarse 24 by 24 grid covering Central
+America, from Jan 1995 to Dec 2000. The data is stored in a 3d area with
+the first two dimensions representing latitude and longitude, and the third
+representing time.
 }
 \examples{
 value <- ozone[1, 1, ]
@@ -35,7 +37,7 @@ dim(coefs)
 dim(deseas)
 }
 \references{
-  \url{http://stat-computing.org/dataexpo/2006/}
+\url{http://stat-computing.org/dataexpo/2006/}
 }
 \keyword{datasets}
 
diff --git a/man/plyr.Rd b/man/plyr.Rd
index 6317892..33dce14 100644
--- a/man/plyr.Rd
+++ b/man/plyr.Rd
@@ -1,28 +1,32 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \docType{package}
 \name{plyr}
 \alias{plyr}
 \alias{plyr-package}
 \title{plyr: the split-apply-combine paradigm for R.}
 \description{
-  The plyr package is a set of clean and consistent tools
-  that implement the split-apply-combine pattern in R. This
-  is an extremely common pattern in data analysis: you
-  solve a complex problem by breaking it down into small
-  pieces, doing something to each piece and then combining
-  the results back together again.
+The plyr package is a set of clean and consistent tools that implement the
+split-apply-combine pattern in R. This is an extremely common pattern in
+data analysis: you solve a complex problem by breaking it down into small
+pieces, doing something to each piece and then combining the results back
+together again.
 }
 \details{
-  The plyr functions are named according to what sort of
-  data structure they split up and what sort of data
-  structure they return:
+The plyr functions are named according to what sort of data structure they
+split up and what sort of data structure they return:
 
-  \describe{ \item{a}{array} \item{l}{list}
-  \item{d}{data.frame} \item{m}{multiple inputs}
-  \item{r}{repeat multiple times} \item{_}{nothing} }
+\describe{
+  \item{a}{array}
+  \item{l}{list}
+  \item{d}{data.frame}
+  \item{m}{multiple inputs}
+  \item{r}{repeat multiple times}
+  \item{_}{nothing}
+}
 
-  So \code{\link{ddply}} takes a data frame as input and
-  returns a data frame as output, and \code{\link{l_ply}}
-  takes a list as input and returns nothing as output.
+So \code{\link{ddply}} takes a data frame as input and returns a data frame
+as output, and \code{\link{l_ply}} takes a list as input and returns nothing
+as output.
 }
 \section{Row names}{
   By design, no plyr function will preserve row names - in
diff --git a/man/print.quoted.Rd b/man/print.quoted.Rd
index 4a60ba6..8760fa4 100644
--- a/man/print.quoted.Rd
+++ b/man/print.quoted.Rd
@@ -1,11 +1,12 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{print.quoted}
 \alias{print.quoted}
 \title{Print quoted variables.}
 \usage{
-  \method{print}{quoted} (x, ...)
+\method{print}{quoted}(x, ...)
 }
 \description{
-  Display the \code{\link{str}}ucture of quoted variables
+Display the \code{\link{str}}ucture of quoted variables
 }
 \keyword{internal}
 
diff --git a/man/print.split.Rd b/man/print.split.Rd
index 7146920..09915f5 100644
--- a/man/print.split.Rd
+++ b/man/print.split.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{print.split}
 \alias{print.split}
 \title{Print split.}
 \usage{
-  \method{print}{split} (x, ...)
+\method{print}{split}(x, ...)
 }
 \arguments{
   \item{x}{object to print}
@@ -10,7 +11,7 @@
   \item{...}{unused}
 }
 \description{
-  Don't print labels, so it appears like a regular list
+Don't print labels, so it appears like a regular list
 }
 \keyword{internal}
 
diff --git a/man/progress_none.Rd b/man/progress_none.Rd
index 35441b8..473c2b4 100644
--- a/man/progress_none.Rd
+++ b/man/progress_none.Rd
@@ -1,22 +1,23 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{progress_none}
 \alias{progress_none}
 \title{Null progress bar}
 \usage{
-  progress_none()
+progress_none()
 }
 \description{
-  A progress bar that does nothing
+A progress bar that does nothing
 }
 \details{
-  This the default progress bar used by plyr functions.
-  It's very simple to understand - it does nothing!
+This the default progress bar used by plyr functions.  It's very simple to
+understand - it does nothing!
 }
 \examples{
 l_ply(1:100, identity, .progress = "none")
 }
 \seealso{
-  Other progress bars: \code{\link{progress_text}},
-  \code{\link{progress_time}}, \code{\link{progress_tk}},
+Other progress bars: \code{\link{progress_text}};
+  \code{\link{progress_time}}; \code{\link{progress_tk}};
   \code{\link{progress_win}}
 }
 \keyword{internal}
diff --git a/man/progress_text.Rd b/man/progress_text.Rd
index f5be954..9c64c38 100644
--- a/man/progress_text.Rd
+++ b/man/progress_text.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{progress_text}
 \alias{progress_text}
 \title{Text progress bar.}
 \usage{
-  progress_text(style = 3, ...)
+progress_text(style = 3, ...)
 }
 \arguments{
   \item{style}{style of text bar, see Details section of
@@ -12,21 +13,20 @@
   \code{\link{txtProgressBar}}}
 }
 \description{
-  A textual progress bar
+A textual progress bar
 }
 \details{
-  This progress bar displays a textual progress bar that
-  works on all platforms.  It is a thin wrapper around the
-  built-in \code{\link{setTxtProgressBar}} and can be
-  customised in the same way.
+This progress bar displays a textual progress bar that works on all
+platforms.  It is a thin wrapper around the built-in
+\code{\link{setTxtProgressBar}} and can be customised in the same way.
 }
 \examples{
 l_ply(1:100, identity, .progress = "text")
 l_ply(1:100, identity, .progress = progress_text(char = "-"))
 }
 \seealso{
-  Other progress bars: \code{\link{progress_none}},
-  \code{\link{progress_time}}, \code{\link{progress_tk}},
+Other progress bars: \code{\link{progress_none}};
+  \code{\link{progress_time}}; \code{\link{progress_tk}};
   \code{\link{progress_win}}
 }
 
diff --git a/man/progress_time.Rd b/man/progress_time.Rd
index 4834654..7c22c7e 100644
--- a/man/progress_time.Rd
+++ b/man/progress_time.Rd
@@ -1,20 +1,20 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{progress_time}
 \alias{progress_time}
 \title{Text progress bar with time.}
 \usage{
-  progress_time()
+progress_time()
 }
 \description{
-  A textual progress bar that estimates time remaining. It
-  displays the estimated time remaining and, when finished,
-  total duration.
+A textual progress bar that estimates time remaining. It displays the
+estimated time remaining and, when finished, total duration.
 }
 \examples{
 l_ply(1:100, function(x) Sys.sleep(.01), .progress = "time")
 }
 \seealso{
-  Other progress bars: \code{\link{progress_none}},
-  \code{\link{progress_text}}, \code{\link{progress_tk}},
+Other progress bars: \code{\link{progress_none}};
+  \code{\link{progress_text}}; \code{\link{progress_tk}};
   \code{\link{progress_win}}
 }
 
diff --git a/man/progress_tk.Rd b/man/progress_tk.Rd
index 27fe8e8..c0d3e3b 100644
--- a/man/progress_tk.Rd
+++ b/man/progress_tk.Rd
@@ -1,9 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{progress_tk}
 \alias{progress_tk}
 \title{Graphical progress bar, powered by Tk.}
 \usage{
-  progress_tk(title = "plyr progress",
-    label = "Working...", ...)
+progress_tk(title = "plyr progress", label = "Working...", ...)
 }
 \arguments{
   \item{title}{window title}
@@ -14,10 +14,10 @@
   \code{\link[tcltk]{tkProgressBar}}}
 }
 \description{
-  A graphical progress bar displayed in a Tk window
+A graphical progress bar displayed in a Tk window
 }
 \details{
-  This graphical progress will appear in a separate window.
+This graphical progress will appear in a separate window.
 }
 \examples{
 \dontrun{
@@ -27,11 +27,10 @@ l_ply(1:100, identity, .progress = progress_tk(label=""))
 }
 }
 \seealso{
-  \code{\link[tcltk]{tkProgressBar}} for the function that
-  powers this progress bar
+\code{\link[tcltk]{tkProgressBar}} for the function that powers this progress bar
 
-  Other progress bars: \code{\link{progress_none}},
-  \code{\link{progress_text}}, \code{\link{progress_time}},
+Other progress bars: \code{\link{progress_none}};
+  \code{\link{progress_text}}; \code{\link{progress_time}};
   \code{\link{progress_win}}
 }
 
diff --git a/man/progress_win.Rd b/man/progress_win.Rd
index fa8adbe..1b66bd1 100644
--- a/man/progress_win.Rd
+++ b/man/progress_win.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{progress_win}
 \alias{progress_win}
 \title{Graphical progress bar, powered by Windows.}
 \usage{
-  progress_win(title = "plyr progress", ...)
+progress_win(title = "plyr progress", ...)
 }
 \arguments{
   \item{title}{window title}
@@ -11,10 +12,10 @@
   \code{winProgressBar}}
 }
 \description{
-  A graphical progress bar displayed in a separate window
+A graphical progress bar displayed in a separate window
 }
 \details{
-  This graphical progress only works on Windows.
+This graphical progress only works on Windows.
 }
 \examples{
 if(exists("winProgressBar")) {
@@ -23,11 +24,10 @@ l_ply(1:100, identity, .progress = progress_win(title="Working..."))
 }
 }
 \seealso{
-  \code{winProgressBar} for the function that powers this
-  progress bar
+\code{winProgressBar} for the function that powers this progress bar
 
-  Other progress bars: \code{\link{progress_none}},
-  \code{\link{progress_text}}, \code{\link{progress_time}},
+Other progress bars: \code{\link{progress_none}};
+  \code{\link{progress_text}}; \code{\link{progress_time}};
   \code{\link{progress_tk}}
 }
 
diff --git a/man/quickdf.Rd b/man/quickdf.Rd
index 6e3efac..e8a81c7 100644
--- a/man/quickdf.Rd
+++ b/man/quickdf.Rd
@@ -1,16 +1,17 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{quickdf}
 \alias{quickdf}
 \title{Quick data frame.}
 \usage{
-  quickdf(list)
+quickdf(list)
 }
 \arguments{
   \item{list}{list to convert to data frame}
 }
 \description{
-  Experimental version of \code{\link{as.data.frame}} that
-  converts a list to a data frame, but doesn't do any
-  checks to make sure it's a valid format.  Much faster.
+Experimental version of \code{\link{as.data.frame}} that converts a
+list to a data frame, but doesn't do any checks to make sure it's a
+valid format.  Much faster.
 }
 \keyword{internal}
 
diff --git a/man/quoted.Rd b/man/quoted.Rd
index 87dc6c7..f80a173 100644
--- a/man/quoted.Rd
+++ b/man/quoted.Rd
@@ -1,3 +1,4 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{.}
 \alias{.}
 \alias{is.quoted}
@@ -5,7 +6,7 @@
 \title{Quote variables to create a list of unevaluated expressions for later
 evaluation.}
 \usage{
-  .(..., .env = parent.frame())
+.(..., .env = parent.frame())
 }
 \arguments{
   \item{...}{unevaluated expressions to be recorded.
@@ -17,23 +18,22 @@ evaluation.}
   environment in which \code{.} was executed.}
 }
 \value{
-  list of symbol and language primitives
+list of symbol and language primitives
 }
 \description{
-  This function is similar to \code{\link{~}} in that it is
-  used to capture the name of variables, not their current
-  value.  This is used throughout plyr to specify the names
-  of variables (or more complicated expressions).
+This function is similar to \code{\link{~}} in that it is used to
+capture the name of variables, not their current value.  This is used
+throughout plyr to specify the names of variables (or more complicated
+expressions).
 }
 \details{
-  Similar tricks can be performed with
-  \code{\link{substitute}}, but when functions can be
-  called in multiple ways it becomes increasingly tricky to
-  ensure that the values are extracted from the correct
-  frame.  Substitute tricks also make it difficult to
-  program against the functions that use them, while the
-  \code{quoted} class provides \code{as.quoted.character}
-  to convert strings to the appropriate data structure.
+Similar tricks can be performed with \code{\link{substitute}}, but when
+functions can be called in multiple ways it becomes increasingly tricky
+to ensure that the values are extracted from the correct frame.  Substitute
+tricks also make it difficult to program against the functions that use
+them, while the \code{quoted} class provides
+\code{as.quoted.character} to convert strings to the appropriate
+data structure.
 }
 \examples{
 .(a, b, c)
diff --git a/man/r_ply.Rd b/man/r_ply.Rd
index fb9831e..a859643 100644
--- a/man/r_ply.Rd
+++ b/man/r_ply.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{r_ply}
 \alias{r_ply}
 \title{Replicate expression and discard results.}
 \usage{
-  r_ply(.n, .expr, .progress = "none", .print = FALSE)
+r_ply(.n, .expr, .progress = "none", .print = FALSE)
 }
 \arguments{
   \item{.n}{number of times to evaluate the expression}
@@ -16,21 +17,21 @@
   \code{FALSE})}
 }
 \description{
-  Evalulate expression n times then discard results
+Evalulate expression n times then discard results
 }
 \details{
-  This function runs an expression multiple times,
-  discarding the results. This function is equivalent to
-  \code{\link{replicate}}, but never returns anything
+This function runs an expression multiple times, discarding the results.
+This function is equivalent to \code{\link{replicate}}, but never returns
+anything
 }
 \examples{
 r_ply(10, plot(runif(50)))
 r_ply(25, hist(runif(1000)))
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy for
+  Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \keyword{manip}
 
diff --git a/man/raply.Rd b/man/raply.Rd
index b06d16d..28df831 100644
--- a/man/raply.Rd
+++ b/man/raply.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{raply}
 \alias{raply}
 \title{Replicate expression and return results in a array.}
 \usage{
-  raply(.n, .expr, .progress = "none", .drop = TRUE)
+raply(.n, .expr, .progress = "none", .drop = TRUE)
 }
 \arguments{
   \item{.n}{number of times to evaluate the expression}
@@ -17,21 +18,17 @@
   \code{TRUE}}
 }
 \value{
-  if results are atomic with same type and dimensionality,
-  a vector, matrix or array; otherwise, a list-array (a
-  list with dimensions)
+if results are atomic with same type and dimensionality, a vector, matrix or array; otherwise, a list-array (a list with dimensions)
 }
 \description{
-  Evalulate expression n times then combine results into an
-  array
+Evalulate expression n times then combine results into an array
 }
 \details{
-  This function runs an expression multiple times, and
-  combines the result into a data frame.  If there are no
-  results, then this function returns a vector of length 0
-  (\code{vector(0)}). This function is equivalent to
-  \code{\link{replicate}}, but will always return results
-  as a vector, matrix or array.
+This function runs an expression multiple times, and combines the
+result into a data frame.  If there are no results, then this function
+returns a vector of length 0 (\code{vector(0)}).
+This function is equivalent to \code{\link{replicate}}, but will always
+return results as a vector, matrix or array.
 }
 \examples{
 raply(100, mean(runif(100)))
@@ -46,9 +43,9 @@ hist(raply(1000, mean(rexp(100))))
 hist(raply(1000, mean(rexp(1000))))
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy for
+  Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \keyword{manip}
 
diff --git a/man/rbind.fill.Rd b/man/rbind.fill.Rd
index 2b93564..9d7a3b7 100644
--- a/man/rbind.fill.Rd
+++ b/man/rbind.fill.Rd
@@ -1,36 +1,43 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{rbind.fill}
 \alias{rbind.fill}
 \title{Combine data.frames by row, filling in missing columns.}
 \usage{
-  rbind.fill(...)
+rbind.fill(...)
 }
 \arguments{
   \item{...}{input data frames to row bind together.  The
   first argument can be a list of data frames, in which
-  case all other arguments are ignored.}
+  case all other arguments are ignored.  Any NULL inputs
+  are silently dropped. If all inputs are NULL, the output
+  is NULL.}
 }
 \value{
-  a single data frame
+a single data frame
 }
 \description{
-  \code{rbind}s a list of data frames filling missing
-  columns with NA.
+\code{rbind}s a list of data frames filling missing columns with NA.
 }
 \details{
-  This is an enhancement to \code{\link{rbind}} that adds
-  in columns that are not present in all inputs, accepts a
-  list of data frames, and operates substantially faster.
+This is an enhancement to \code{\link{rbind}} that adds in columns
+that are not present in all inputs, accepts a list of data frames, and
+operates substantially faster.
 
-  Column names and types in the output will appear in the
-  order in which they were encountered. No checking is
-  performed to ensure that each column is of consistent
-  type in the inputs.
+Column names and types in the output will appear in the order in which
+they were encountered.
+
+Unordered factor columns will have their levels unified and
+character data bound with factors will be converted to
+character. POSIXct data will be converted to be in the same time
+zone. Array and matrix columns must have identical dimensions after
+the row count. Aside from these there are no general checks that
+each column is of consistent data type.
 }
 \examples{
 rbind.fill(mtcars[c("mpg", "wt")], mtcars[c("wt", "cyl")])
 }
 \seealso{
-  Other binding functions: \code{\link{rbind.fill.matrix}}
+Other binding functions: \code{\link{rbind.fill.matrix}}
 }
 \keyword{manip}
 
diff --git a/man/rbind.fill.matrix.Rd b/man/rbind.fill.matrix.Rd
index 431a1d7..1cc19cd 100644
--- a/man/rbind.fill.matrix.Rd
+++ b/man/rbind.fill.matrix.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{rbind.fill.matrix}
 \alias{rbind.fill.matrix}
 \title{Bind matrices by row, and fill missing columns with NA.}
 \usage{
-  rbind.fill.matrix(...)
+rbind.fill.matrix(...)
 }
 \arguments{
   \item{...}{the matrices to rbind. The first argument can
@@ -10,28 +11,25 @@
   are ignored.}
 }
 \value{
-  a matrix with column names
+a matrix with column names
 }
 \description{
-  The matrices are bound together using their column names
-  or the column indices (in that order of precedence.)
-  Numeric columns may be converted to character beforehand,
-  e.g. using format.  If a matrix doesn't have colnames,
-  the column number is used. Note that this means that a
-  column with name \code{"1"} is merged with the first
-  column of a matrix without name and so on. The returned
-  matrix will always have column names.
+The matrices are bound together using their column names or the column
+indices (in that order of precedence.) Numeric columns may be converted to
+character beforehand, e.g. using format.  If a matrix doesn't have
+colnames, the column number is used. Note that this means that a
+column with name \code{"1"} is merged with the first column of a matrix
+without name and so on. The returned matrix will always have column names.
 }
 \details{
-  Vectors are converted to 1-column matrices.
+Vectors are converted to 1-column matrices.
 
-  Matrices of factors are not supported. (They are anyways
-  quite inconvenient.) You may convert them first to either
-  numeric or character matrices. If a matrices of different
-  types are merged, then normal covnersion precendence will
-  apply.
+Matrices of factors are not supported. (They are anyways quite
+inconvenient.) You may convert them first to either numeric or character
+matrices. If a matrices of different types are merged, then normal
+covnersion precendence will apply.
 
-  Row names are ignored.
+Row names are ignored.
 }
 \examples{
 A <- matrix (1:4, 2)
@@ -47,13 +45,13 @@ rbind.fill.matrix (A, B)
 rbind.fill.matrix (A, 99)
 }
 \author{
-  C. Beleites
+C. Beleites
 }
 \seealso{
-  \code{\link[base]{rbind}}, \code{\link[base]{cbind}},
-  \code{\link[plyr]{rbind.fill}}
+\code{\link[base]{rbind}}, \code{\link[base]{cbind}},
+   \code{\link[plyr]{rbind.fill}}
 
-  Other binding functions: \code{\link{rbind.fill}}
+Other binding functions: \code{\link{rbind.fill}}
 }
 \keyword{manip}
 
diff --git a/man/rdply.Rd b/man/rdply.Rd
index 2d7aafc..ce3da6b 100644
--- a/man/rdply.Rd
+++ b/man/rdply.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{rdply}
 \alias{rdply}
 \title{Replicate expression and return results in a data frame.}
 \usage{
-  rdply(.n, .expr, .progress = "none")
+rdply(.n, .expr, .progress = "none", .id = NA)
 }
 \arguments{
   \item{.n}{number of times to evaluate the expression}
@@ -11,21 +12,25 @@
 
   \item{.progress}{name of the progress bar to use, see
   \code{\link{create_progress_bar}}}
+
+  \item{.id}{name of the index column. Pass \code{NULL} to
+  avoid creation of the index column. For compatibility,
+  omit this argument or pass \code{NA} to avoid converting
+  the index column to a factor; in this case, \code{".n"}
+  is used as colum name..}
 }
 \value{
-  a data frame
+a data frame
 }
 \description{
-  Evalulate expression n times then combine results into a
-  data frame
+Evalulate expression n times then combine results into a data frame
 }
 \details{
-  This function runs an expression multiple times, and
-  combines the result into a data frame.  If there are no
-  results, then this function returns a data frame with
-  zero rows and columns (\code{data.frame()}). This
-  function is equivalent to \code{\link{replicate}}, but
-  will always return results as a data frame.
+This function runs an expression multiple times, and combines the result into
+a data frame.  If there are no results, then this function returns a data
+frame with zero rows and columns (\code{data.frame()}). This function is
+equivalent to \code{\link{replicate}}, but will always return results as a
+data frame.
 }
 \examples{
 rdply(20, mean(runif(100)))
@@ -33,9 +38,9 @@ rdply(20, each(mean, var)(runif(100)))
 rdply(20, data.frame(x = runif(2)))
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data
+  Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \keyword{manip}
 
diff --git a/man/reduce_dim.Rd b/man/reduce_dim.Rd
index e55949e..d9c3861 100644
--- a/man/reduce_dim.Rd
+++ b/man/reduce_dim.Rd
@@ -1,14 +1,15 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{reduce_dim}
 \alias{reduce_dim}
 \title{Reduce dimensions.}
 \usage{
-  reduce_dim(x)
+reduce_dim(x)
 }
 \arguments{
   \item{x}{array}
 }
 \description{
-  Remove extraneous dimensions
+Remove extraneous dimensions
 }
 \keyword{internal}
 
diff --git a/man/rename.Rd b/man/rename.Rd
index 8ea4ac5..ba8229e 100644
--- a/man/rename.Rd
+++ b/man/rename.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{rename}
 \alias{rename}
 \title{Modify names by name, not position.}
 \usage{
-  rename(x, replace, warn_missing = TRUE)
+rename(x, replace, warn_missing = TRUE)
 }
 \arguments{
   \item{x}{named object to modify}
@@ -16,7 +17,7 @@
   returned data into a variable.}
 }
 \description{
-  Modify names by name, not position.
+Modify names by name, not position.
 }
 \examples{
 x <- c("a" = 1, "b" = 2, d = 3, 4)
diff --git a/man/revalue.Rd b/man/revalue.Rd
index c8b8f87..6e77f56 100644
--- a/man/revalue.Rd
+++ b/man/revalue.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{revalue}
 \alias{revalue}
 \title{Replace specified values with new values, in a factor or character vector.}
 \usage{
-  revalue(x, replace = NULL, warn_missing = TRUE)
+revalue(x, replace = NULL, warn_missing = TRUE)
 }
 \arguments{
   \item{x}{factor or character vector to modify}
@@ -14,15 +15,14 @@
   values are not actually present in \code{x}}
 }
 \description{
-  If \code{x} is a factor, the named levels of the factor
-  will be replaced with the new values.
+If \code{x} is a factor, the named levels of the factor will be
+replaced with the new values.
 }
 \details{
-  This function works only on character vectors and
-  factors, but the related \code{mapvalues} function works
-  on vectors of any type and factors, and instead of a
-  named vector specifying the original and replacement
-  values, it takes two separate vectors
+This function works only on character vectors and factors, but the
+related \code{mapvalues} function works on vectors of any type and factors,
+and instead of a named vector specifying the original and replacement values,
+it takes two separate vectors
 }
 \examples{
 x <- c("a", "b", "c")
@@ -33,7 +33,6 @@ y <- factor(c("a", "b", "c", "a"))
 revalue(y, c(a = "A", c = "C"))
 }
 \seealso{
-  \code{\link{mapvalues}} to replace values with vectors of
-  any type
+\code{\link{mapvalues}} to replace values with vectors of any type
 }
 
diff --git a/man/rlply.Rd b/man/rlply.Rd
index 08ebdb4..cf53ec5 100644
--- a/man/rlply.Rd
+++ b/man/rlply.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{rlply}
 \alias{rlply}
 \title{Replicate expression and return results in a list.}
 \usage{
-  rlply(.n, .expr, .progress = "none")
+rlply(.n, .expr, .progress = "none")
 }
 \arguments{
   \item{.n}{number of times to evaluate the expression}
@@ -13,28 +14,25 @@
   \code{\link{create_progress_bar}}}
 }
 \value{
-  list of results
+list of results
 }
 \description{
-  Evalulate expression n times then combine results into a
-  list
+Evalulate expression n times then combine results into a list
 }
 \details{
-  This function runs an expression multiple times, and
-  combines the result into a list.  If there are no
-  results, then this function will return a list of length
-  0 (\code{list()}). This function is equivalent to
-  \code{\link{replicate}}, but will always return results
-  as a list.
+This function runs an expression multiple times, and combines the
+result into a list.  If there are no results, then this function will return
+a list of length 0  (\code{list()}). This function is equivalent to
+\code{\link{replicate}}, but will always return results as a list.
 }
 \examples{
 mods <- rlply(100, lm(y ~ x, data=data.frame(x=rnorm(100), y=rnorm(100))))
 hist(laply(mods, function(x) summary(x)$r.squared))
 }
 \references{
-  Hadley Wickham (2011). The Split-Apply-Combine Strategy
-  for Data Analysis. Journal of Statistical Software,
-  40(1), 1-29.  \url{http://www.jstatsoft.org/v40/i01/}.
+Hadley Wickham (2011). The Split-Apply-Combine Strategy for
+  Data Analysis. Journal of Statistical Software, 40(1), 1-29.
+  \url{http://www.jstatsoft.org/v40/i01/}.
 }
 \keyword{manip}
 
diff --git a/man/round_any.Rd b/man/round_any.Rd
index 8b23f29..a3e807e 100644
--- a/man/round_any.Rd
+++ b/man/round_any.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{round_any}
 \alias{round_any}
 \title{Round to multiple of any number.}
 \usage{
-  round_any(x, accuracy, f = round)
+round_any(x, accuracy, f = round)
 }
 \arguments{
   \item{x}{numeric or date-time (POSIXct) vector to round}
@@ -14,7 +15,7 @@
   \code{\link{ceiling}} or \code{\link{round}}}
 }
 \description{
-  Round to multiple of any number.
+Round to multiple of any number.
 }
 \examples{
 round_any(135, 10)
diff --git a/man/splat.Rd b/man/splat.Rd
index 1de1ed3..c9c9390 100644
--- a/man/splat.Rd
+++ b/man/splat.Rd
@@ -1,24 +1,23 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{splat}
 \alias{splat}
 \title{`Splat' arguments to a function.}
 \usage{
-  splat(flat)
+splat(flat)
 }
 \arguments{
   \item{flat}{function to splat}
 }
 \value{
-  a function
+a function
 }
 \description{
-  Wraps a function in do.call, so instead of taking
-  multiple arguments, it takes a single named list which
-  will be interpreted as its arguments.
+Wraps a function in do.call, so instead of taking multiple arguments, it
+takes a single named list which will be interpreted as its arguments.
 }
 \details{
-  This is useful when you want to pass a function a row of
-  data frame or array, and don't want to manually pull it
-  apart in your function.
+This is useful when you want to pass a function a row of data frame or
+array, and don't want to manually pull it apart in your function.
 }
 \examples{
 hp_per_cyl <- function(hp, cyl, ...) hp / cyl
diff --git a/man/split_indices.Rd b/man/split_indices.Rd
index 2e5bbc2..c300422 100644
--- a/man/split_indices.Rd
+++ b/man/split_indices.Rd
@@ -1,20 +1,23 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{split_indices}
 \alias{split_indices}
 \title{Split indices.}
 \usage{
-  split_indices(group, n = max(group))
+split_indices(group, n = 0L)
 }
 \arguments{
   \item{index}{integer indices}
 
-  \item{group}{integer groups}
-
-  \item{n}{largest integer (may not appear in index)}
+  \item{n}{largest integer (may not appear in index). This
+  is hint: if the largest value of \code{group} is bigger
+  than \code{n}, the output will silently expand.}
 }
 \description{
-  An optimised version of split for the special case of
-  splitting row indices into groups, as used by
-  \code{\link{splitter_d}}
+An optimised version of split for the special case of splitting row
+indices into groups, as used by \code{\link{splitter_d}}
+}
+\examples{
+split_indices(sample(10, 100, rep = TRUE), 10)
 }
 \keyword{internal}
 \keyword{manip}
diff --git a/man/split_labels.Rd b/man/split_labels.Rd
index 4532889..af91665 100644
--- a/man/split_labels.Rd
+++ b/man/split_labels.Rd
@@ -1,9 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{split_labels}
 \alias{split_labels}
 \title{Generate labels for split data frame.}
 \usage{
-  split_labels(splits, drop,
-    id = plyr::id(splits, drop = TRUE))
+split_labels(splits, drop, id = plyr::id(splits, drop = TRUE))
 }
 \arguments{
   \item{list}{of variables to split up by}
@@ -12,7 +12,7 @@
   considered, or only those present in the data}
 }
 \description{
-  Create data frame giving labels for split data frame.
+Create data frame giving labels for split data frame.
 }
 \keyword{internal}
 
diff --git a/man/splitter_a.Rd b/man/splitter_a.Rd
index 74b3796..9a0ea79 100644
--- a/man/splitter_a.Rd
+++ b/man/splitter_a.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{splitter_a}
 \alias{splitter_a}
 \title{Split an array by .margins.}
 \usage{
-  splitter_a(data, .margins = 1L, .expand = TRUE)
+splitter_a(data, .margins = 1L, .expand = TRUE)
 }
 \arguments{
   \item{data}{>1d data structure (matrix, data.frame or
@@ -17,25 +18,22 @@
   variable.}
 }
 \value{
-  a list of lower-d slices, with attributes that record
-  split details
+a list of lower-d slices, with attributes that record split details
 }
 \description{
-  Split a 2d or higher data structure into lower-d pieces
-  based
+Split a 2d or higher data structure into lower-d pieces based
 }
 \details{
-  This is the workhorse of the \code{a*ply} functions.
-  Given a >1 d data structure (matrix, array, data.frame),
-  it splits it into pieces based on the subscripts that you
-  supply.  Each piece is a lower dimensional slice.
+This is the workhorse of the \code{a*ply} functions.  Given a >1 d
+data structure (matrix, array, data.frame), it splits it into pieces
+based on the subscripts that you supply.  Each piece is a lower dimensional
+slice.
 
-  The margins are specified in the same way as
-  \code{\link{apply}}, but \code{splitter_a} just splits up
-  the data, while \code{apply} also applies a function and
-  combines the pieces back together.  This function also
-  includes enough information to recreate the split from
-  attributes on the list of pieces.
+The margins are specified in the same way as \code{\link{apply}}, but
+\code{splitter_a} just splits up the data, while \code{apply} also
+applies a function and combines the pieces back together.  This function
+also includes enough information to recreate the split from attributes on
+the list of pieces.
 }
 \examples{
 plyr:::splitter_a(mtcars, 1)
@@ -46,7 +44,7 @@ plyr:::splitter_a(ozone, 3)
 plyr:::splitter_a(ozone, 1:2)
 }
 \seealso{
-  Other splitter functions: \code{\link{splitter_d}}
+Other splitter functions: \code{\link{splitter_d}}
 }
 \keyword{internal}
 
diff --git a/man/splitter_d.Rd b/man/splitter_d.Rd
index 669e8ee..3475dcc 100644
--- a/man/splitter_d.Rd
+++ b/man/splitter_d.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{splitter_d}
 \alias{splitter_d}
 \title{Split a data frame by variables.}
 \usage{
-  splitter_d(data, .variables = NULL, drop = TRUE)
+splitter_d(data, .variables = NULL, drop = TRUE)
 }
 \arguments{
   \item{data}{data frame}
@@ -12,25 +13,21 @@
   \item{drop}{drop unnused factor levels?}
 }
 \value{
-  a list of data.frames, with attributes that record split
-  details
+a list of data.frames, with attributes that record split details
 }
 \description{
-  Split a data frame into pieces based on variable
-  contained in that data frame
+Split a data frame into pieces based on variable contained in that data frame
 }
 \details{
-  This is the workhorse of the \code{d*ply} functions.
-  Based on the variables you supply, it breaks up a single
-  data frame into a list of data frames, each containing a
-  single combination from the levels of the specified
-  variables.
+This is the workhorse of the \code{d*ply} functions.  Based on the variables
+you supply, it breaks up a single data frame into a list of data frames,
+each containing a single combination from the levels of the specified
+variables.
 
-  This is basically a thin wrapper around
-  \code{\link{split}} which evaluates the variables in the
-  context of the data, and includes enough information to
-  reconstruct the labelling of the data frame after other
-  operations.
+This is basically a thin wrapper around \code{\link{split}} which
+evaluates the variables in the context of the data, and includes enough
+information to reconstruct the labelling of the data frame after
+other operations.
 }
 \examples{
 plyr:::splitter_d(mtcars, .(cyl))
@@ -47,10 +44,9 @@ plyr:::splitter_d(mtcars, .(cyl3, vs))
 plyr:::splitter_d(mtcars, .(cyl3, vs), drop = FALSE)
 }
 \seealso{
-  \code{\link{.}} for quoting variables,
-  \code{\link{split}}
+\code{\link{.}} for quoting variables, \code{\link{split}}
 
-  Other splitter functions: \code{\link{splitter_a}}
+Other splitter functions: \code{\link{splitter_a}}
 }
 \keyword{internal}
 
diff --git a/man/strip_splits.Rd b/man/strip_splits.Rd
index ee92df8..94f2110 100644
--- a/man/strip_splits.Rd
+++ b/man/strip_splits.Rd
@@ -1,18 +1,18 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{strip_splits}
 \alias{strip_splits}
 \title{Remove splitting variables from a data frame.}
 \usage{
-  strip_splits(df)
+strip_splits(df)
 }
 \arguments{
   \item{df}{data frame produced by \code{d*ply}.}
 }
 \description{
-  This is useful when you want to perform some operation to
-  every column in the data frame, except the variables that
-  you have used to split it. These variables will be
-  automatically added back on to the result when combining
-  all results together.
+This is useful when you want to perform some operation to every column
+in the data frame, except the variables that you have used to split it.
+These variables will be automatically added back on to the result when
+combining all results together.
 }
 \examples{
 dlply(mtcars, c("vs", "am"))
diff --git a/man/summarise.Rd b/man/summarise.Rd
index 17200d5..6a29899 100644
--- a/man/summarise.Rd
+++ b/man/summarise.Rd
@@ -1,9 +1,10 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{summarise}
 \alias{summarise}
 \alias{summarize}
 \title{Summarise a data frame.}
 \usage{
-  summarise(.data, ...)
+summarise(.data, ...)
 }
 \arguments{
   \item{.data}{the data frame to be summarised}
@@ -11,11 +12,15 @@
   \item{...}{further arguments of the form var = value}
 }
 \description{
-  Summarise works in an analagous way to transform, except
-  instead of adding columns to an existing data frame, it
-  creates a new data frame.  This is particularly useful in
-  conjunction with \code{\link{ddply}} as it makes it easy
-  to perform group-wise summaries.
+Summarise works in an analogous way to \code{\link{mutate}}, except
+instead of adding columns to an existing data frame, it creates a new
+data frame.  This is particularly useful in conjunction with
+\code{\link{ddply}} as it makes it easy to perform group-wise summaries.
+}
+\note{
+Be careful when using existing variable names; the corresponding
+columns will be immediately updated with the new data and this can affect
+subsequent operations referring to those variables.
 }
 \examples{
 # Let's extract the number of teams and total period of time
diff --git a/man/take.Rd b/man/take.Rd
index 8fb47ff..b74a232 100644
--- a/man/take.Rd
+++ b/man/take.Rd
@@ -1,8 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{take}
 \alias{take}
 \title{Take a subset along an arbitrary dimension}
 \usage{
-  take(x, along, indices, drop = FALSE)
+take(x, along, indices, drop = FALSE)
 }
 \arguments{
   \item{x}{matrix or array to subset}
@@ -16,7 +17,7 @@
   opposite of the useful R default.}
 }
 \description{
-  Take a subset along an arbitrary dimension
+Take a subset along an arbitrary dimension
 }
 \examples{
 x <- array(seq_len(3 * 4 * 5), c(3, 4, 5))
diff --git a/man/true.Rd b/man/true.Rd
index 4084dd6..d20fc58 100644
--- a/man/true.Rd
+++ b/man/true.Rd
@@ -1,20 +1,21 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{true}
 \alias{true}
 \title{Function that always returns true.}
 \usage{
-  true(...)
+true(...)
 }
 \arguments{
   \item{...}{all input ignored}
 }
 \value{
-  \code{TRUE}
+\code{TRUE}
 }
 \description{
-  Function that always returns true.
+Function that always returns true.
 }
 \seealso{
-  \code{\link{colwise}} which uses it
+\code{\link{colwise}} which uses it
 }
 \keyword{internal}
 
diff --git a/man/try_default.Rd b/man/try_default.Rd
index f51d615..a718186 100644
--- a/man/try_default.Rd
+++ b/man/try_default.Rd
@@ -1,9 +1,10 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{try_default}
 \alias{tryNULL}
 \alias{try_default}
 \title{Try, with default in case of error.}
 \usage{
-  try_default(expr, default, quiet = FALSE)
+try_default(expr, default, quiet = FALSE)
 }
 \arguments{
   \item{expr}{expression to try}
@@ -14,15 +15,13 @@
   (FALSE, default)}
 }
 \description{
-  \code{try_default} wraps try so that it returns a default
-  value in the case of error.
+\code{try_default} wraps try so that it returns a default value in the case of error.
 }
 \details{
-  \code{tryNULL} provides a useful special case when
-  dealing with lists.
+\code{tryNULL} provides a useful special case when dealing with lists.
 }
 \seealso{
-  \code{\link{tryapply}}
+\code{\link{tryapply}}
 }
 \keyword{internal}
 
diff --git a/man/tryapply.Rd b/man/tryapply.Rd
index c78613d..3276573 100644
--- a/man/tryapply.Rd
+++ b/man/tryapply.Rd
@@ -1,12 +1,14 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{tryapply}
 \alias{tryapply}
 \title{Apply with built in try.
 Uses compact, lapply and tryNULL}
 \usage{
-  tryapply(list, fun, ...)
+tryapply(list, fun, ...)
 }
 \description{
-  Apply with built in try. Uses compact, lapply and tryNULL
+Apply with built in try.
+Uses compact, lapply and tryNULL
 }
 \keyword{internal}
 
diff --git a/man/unrowname.Rd b/man/unrowname.Rd
index f6eec76..0593054 100644
--- a/man/unrowname.Rd
+++ b/man/unrowname.Rd
@@ -1,14 +1,15 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{unrowname}
 \alias{unrowname}
 \title{Un-rowname.}
 \usage{
-  unrowname(x)
+unrowname(x)
 }
 \arguments{
   \item{x}{data frame}
 }
 \description{
-  Strip rownames from an object
+Strip rownames from an object
 }
 \keyword{internal}
 
diff --git a/man/vaggregate.Rd b/man/vaggregate.Rd
index 44bb836..bf74ab2 100644
--- a/man/vaggregate.Rd
+++ b/man/vaggregate.Rd
@@ -1,9 +1,9 @@
+% Generated by roxygen2 (4.0.0): do not edit by hand
 \name{vaggregate}
 \alias{vaggregate}
 \title{Vector aggregate.}
 \usage{
-  vaggregate(.value, .group, .fun, ..., .default = NULL,
-    .n = nlevels(.group))
+vaggregate(.value, .group, .fun, ..., .default = NULL, .n = nlevels(.group))
 }
 \arguments{
   \item{.value}{vector of values to aggregate}
@@ -21,17 +21,15 @@
   \item{.n}{total number of groups}
 }
 \description{
-  This function is somewhat similar to \code{tapply}, but
-  is designed for use in conjunction with \code{id}. It is
-  simpler in that it only accepts a single grouping vector
-  (use \code{\link{id}} if you have more) and uses
-  \code{\link{vapply}} internally, using the
-  \code{.default} value as the template.
+This function is somewhat similar to \code{tapply}, but is designed for
+use in conjunction with \code{id}. It is simpler in that it only
+accepts a single grouping vector (use \code{\link{id}} if you have more)
+and uses \code{\link{vapply}} internally, using the \code{.default} value
+as the template.
 }
 \details{
-  \code{vaggregate} should be faster than \code{tapply} in
-  most situations because it avoids making a copy of the
-  data.
+\code{vaggregate} should be faster than \code{tapply} in most situations
+because it avoids making a copy of the data.
 }
 \examples{
 # Some examples of use borrowed from ?tapply
diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp
new file mode 100644
index 0000000..eac1875
--- /dev/null
+++ b/src/RcppExports.cpp
@@ -0,0 +1,39 @@
+// This file was generated by Rcpp::compileAttributes
+// Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
+
+#include <Rcpp.h>
+
+using namespace Rcpp;
+
+// loop_apply
+List loop_apply(int n, Function f);
+RcppExport SEXP plyr_loop_apply(SEXP nSEXP, SEXP fSEXP) {
+BEGIN_RCPP
+    SEXP __sexp_result;
+    {
+        Rcpp::RNGScope __rngScope;
+        Rcpp::traits::input_parameter< int >::type n(nSEXP );
+        Rcpp::traits::input_parameter< Function >::type f(fSEXP );
+        List __result = loop_apply(n, f);
+        PROTECT(__sexp_result = Rcpp::wrap(__result));
+    }
+    UNPROTECT(1);
+    return __sexp_result;
+END_RCPP
+}
+// split_indices
+std::vector<std::vector<int> > split_indices(IntegerVector group, int n = 0);
+RcppExport SEXP plyr_split_indices(SEXP groupSEXP, SEXP nSEXP) {
+BEGIN_RCPP
+    SEXP __sexp_result;
+    {
+        Rcpp::RNGScope __rngScope;
+        Rcpp::traits::input_parameter< IntegerVector >::type group(groupSEXP );
+        Rcpp::traits::input_parameter< int >::type n(nSEXP );
+        std::vector<std::vector<int> > __result = split_indices(group, n);
+        PROTECT(__sexp_result = Rcpp::wrap(__result));
+    }
+    UNPROTECT(1);
+    return __sexp_result;
+END_RCPP
+}
diff --git a/src/loop-apply.c b/src/loop-apply.c
deleted file mode 100644
index bb36b22..0000000
--- a/src/loop-apply.c
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <R.h>
-#include <Rdefines.h>
-
-SEXP loop_apply(SEXP n, SEXP f, SEXP rho) {
-  if(!isFunction(f)) error("'f' must be a function");
-  if(!isEnvironment(rho)) error("'rho' should be an environment");
-
-  int n1 = INTEGER(n)[0];
-  
-  SEXP results, R_fcall;
-  PROTECT(results = allocVector(VECSXP, n1));
-  PROTECT(R_fcall = lang2(f, R_NilValue));
-
-  SEXP ii;
-  for(int i = 0; i < n1; i++) {
-    PROTECT(ii = ScalarInteger(i + 1));
-    SETCADR(R_fcall, ii);
-    SET_VECTOR_ELT(results, i, eval(R_fcall, rho));
-    
-    UNPROTECT(1);
-  }
-
-  UNPROTECT(2);
-  return results;
-}
diff --git a/src/loop-apply.cpp b/src/loop-apply.cpp
new file mode 100644
index 0000000..577be20
--- /dev/null
+++ b/src/loop-apply.cpp
@@ -0,0 +1,23 @@
+#include <Rcpp.h>
+using namespace Rcpp;
+
+//' Loop apply
+//'
+//' An optimised version of lapply for the special case of operating on
+//' \code{seq_len(n)}
+//'
+//' @param n length of sequence
+//' @param f function to apply to each integer
+//' @param env environment in which to evaluate function
+//' @useDynLib plyr
+//' @keywords internal manip
+// [[Rcpp::export]]
+List loop_apply(int n, Function f) {
+  List out(n);
+  
+  for(int i = 0; i < n; ++i) {
+    out[i] = f(i + 1);
+  }
+  
+  return out;
+}
diff --git a/src/split-numeric.c b/src/split-numeric.c
deleted file mode 100644
index ad243ee..0000000
--- a/src/split-numeric.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#include <R.h>
-#include <Rdefines.h>
-
-SEXP split_indices(SEXP group, SEXP n) {
-  SEXP vec;
-  int i, j, k;
-
-  int nlevs = INTEGER(n)[0];
-  int nobs = LENGTH(group);  
-  int *pgroup = INTEGER(group);
-  
-  // Count number of cases in each group
-  int counts[nlevs];
-  for (i = 0; i < nlevs; i++)
-    counts[i] = 0;
-  for (i = 0; i < nobs; i++) {
-    j = pgroup[i];
-    if (j > nlevs) error("n smaller than largest index");
-    counts[j - 1]++;
-  }
-
-  // Allocate storage for results
-  PROTECT(vec = allocVector(VECSXP, nlevs));
-  for (i = 0; i < nlevs; i++) {
-    SET_VECTOR_ELT(vec, i, allocVector(INTSXP, counts[i]));
-  }
-
-  // Put indices in groups
-  for (i = 0; i < nlevs; i++) {
-    counts[i] = 0;
-  }
-  for (i = 0; i < nobs; i++) {
-    j = pgroup[i] - 1;
-    k = counts[j];
-    INTEGER(VECTOR_ELT(vec, j))[k] = i + 1;
-    counts[j]++;
-  }
-  UNPROTECT(1);
-  return vec;
-}
diff --git a/src/split-numeric.cpp b/src/split-numeric.cpp
new file mode 100644
index 0000000..97a6ca4
--- /dev/null
+++ b/src/split-numeric.cpp
@@ -0,0 +1,34 @@
+#include <Rcpp.h>
+using namespace Rcpp;
+
+//' Split indices.
+//'
+//' An optimised version of split for the special case of splitting row
+//' indices into groups, as used by \code{\link{splitter_d}}
+//'
+//' @param index integer indices
+//' @param n largest integer (may not appear in index). This is hint: if 
+//'   the largest value of \code{group} is bigger than \code{n}, the output
+//'   will silently expand.
+//' @useDynLib plyr
+//' @keywords internal manip
+//' @export
+//' @examples
+//' split_indices(sample(10, 100, rep = TRUE), 10)
+// [[Rcpp::export]]
+std::vector<std::vector<int> > split_indices(IntegerVector group, int n = 0) {
+  if (n < 0) stop("n must be a positive integer");
+  
+  std::vector<std::vector<int> > ids(n);
+  
+  int nx = group.size();
+  for (int i = 0; i < nx; ++i) {
+    if (group[i] > n) {
+      ids.resize(group[i]);
+    }
+    
+    ids[group[i] - 1].push_back(i + 1);
+  }
+  
+  return ids;
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/r-cran-plyr.git



More information about the debian-med-commit mailing list