[med-svn] [r-cran-bbmisc] 13/15: New upstream version 1.10
Andreas Tille
tille at debian.org
Mon Oct 9 09:22:50 UTC 2017
This is an automated email from the git hooks/post-receive script.
tille pushed a commit to branch master
in repository r-cran-bbmisc.
commit 3fb69549d69f173162561ea7920d26f68f40057d
Author: Andreas Tille <tille at debian.org>
Date: Mon Oct 9 11:18:06 2017 +0200
New upstream version 1.10
---
DESCRIPTION | 32 +++
LICENSE | 3 +
MD5 | 280 +++++++++++++++++++++
NAMESPACE | 131 ++++++++++
NEWS | 156 ++++++++++++
R/FileCache.R | 26 ++
R/addClasses.R | 15 ++
R/argsAsNamedList.R | 22 ++
R/asMatrix.R | 43 ++++
R/asQuoted.R | 18 ++
R/binPack.R | 53 ++++
R/btwn.R | 18 ++
R/capitalizeStrings.R | 43 ++++
R/catf.R | 23 ++
R/checkArg.R | 109 ++++++++
R/checkListElementClass.R | 25 ++
R/chunk.R | 72 ++++++
R/clipString.R | 22 ++
R/coalesce.R | 33 +++
R/collapse.R | 17 ++
R/collapsef.R | 15 ++
R/computeMode.R | 38 +++
R/convertDataFrameCols.R | 52 ++++
R/convertInteger.R | 56 +++++
R/convertListOfRowsToDataFrame.R | 54 ++++
R/convertMatrixType.R | 17 ++
R/convertRowsToList.R | 65 +++++
R/convertToShortString.R | 60 +++++
R/dapply.R | 45 ++++
R/directory.R | 35 +++
R/do.call2.R | 27 ++
R/dropNamed.R | 22 ++
R/ensureVector.R | 43 ++++
R/explode.R | 22 ++
R/extractSubList.R | 72 ++++++
R/factor.R | 24 ++
R/filterNull.R | 10 +
R/getAttributeNames.R | 11 +
R/getClass1.R | 10 +
R/getFirstLast.R | 17 ++
R/getMaxColIndex.R | 55 ++++
R/getMaxIndex.R | 31 +++
R/getOperatingSystem.R | 39 +++
R/getRelativePath.R | 43 ++++
R/getUnixTime.R | 9 +
R/getUsedFactorLevels.R | 12 +
R/hasAttributes.R | 13 +
R/insert.R | 30 +++
R/isExpensiveExampleOk.R | 20 ++
R/isFALSE.R | 12 +
R/isProperlyNamed.R | 16 ++
R/isScalarNA.R | 10 +
R/isScalarValue.R | 70 ++++++
R/isSubset.R | 21 ++
R/isSuperset.R | 15 ++
R/isValidName.R | 18 ++
R/is_error.R | 19 ++
R/itostr.R | 23 ++
R/lib.R | 27 ++
R/load2.R | 50 ++++
R/lsort.R | 14 ++
R/makeDataFrame.R | 60 +++++
R/makeProgressBar.R | 166 ++++++++++++
R/makeS3Obj.R | 16 ++
R/makeSimpleFileLogger.R | 85 +++++++
R/mapValues.R | 55 ++++
R/matchDataFrameSubset.R | 25 ++
R/messagef.R | 16 ++
R/namedList.R | 22 ++
R/names2.R | 26 ++
R/nin.R | 12 +
R/normalize.R | 97 +++++++
R/optimizeSubInts.R | 41 +++
R/pause.R | 6 +
R/printStrToChar.R | 17 ++
R/printToChar.R | 27 ++
R/rangeVal.R | 19 ++
R/requirePackages.R | 99 ++++++++
R/rowLapply.R | 77 ++++++
R/save2.R | 34 +++
R/seq.R | 22 ++
R/setAttribute.R | 16 ++
R/setClasses.R | 14 ++
R/setRowColNames.R | 21 ++
R/setValue.R | 26 ++
R/sortByCol.R | 30 +++
R/splitPath.R | 26 ++
R/splitTime.R | 31 +++
R/stopf.R | 25 ++
R/strrepeat.R | 15 ++
R/suppressAll.R | 25 ++
R/symdiff.R | 11 +
R/system3.R | 53 ++++
R/toRangeStr.R | 34 +++
R/vapply.R | 40 +++
R/warningf.R | 31 +++
R/which.first.R | 23 ++
R/zzz.R | 10 +
R/zzz_deprecated.R | 24 ++
debian/README.test | 9 -
debian/changelog | 44 ----
debian/compat | 1 -
debian/control | 24 --
debian/copyright | 42 ----
debian/docs | 3 -
debian/rules | 8 -
debian/source/format | 1 -
debian/tests/control | 3 -
debian/tests/run-unit-test | 11 -
debian/watch | 2 -
man/addClasses.Rd | 25 ++
man/argsAsNamedList.Rd | 23 ++
man/asMatrixCols.Rd | 30 +++
man/asQuoted.Rd | 27 ++
man/binPack.Rd | 37 +++
man/btwn.Rd | 27 ++
man/cFactor.Rd | 26 ++
man/capitalizeStrings.Rd | 32 +++
man/catf.Rd | 35 +++
man/checkArg.Rd | 85 +++++++
man/checkListElementClass.Rd | 28 +++
man/chunk.Rd | 49 ++++
man/clipString.Rd | 31 +++
man/coalesce.Rd | 26 ++
man/collapse.Rd | 27 ++
man/collapsef.Rd | 25 ++
man/computeMode.Rd | 33 +++
man/convertDataFrameCols.Rd | 36 +++
man/convertInteger.Rd | 27 ++
man/convertIntegers.Rd | 28 +++
man/convertListOfRowsToDataFrame.Rd | 38 +++
man/convertMatrixType.Rd | 25 ++
man/convertRowsToList.Rd | 42 ++++
man/convertToShortString.Rd | 40 +++
man/dapply.Rd | 32 +++
man/deprecated.Rd | 34 +++
man/do.call2.Rd | 36 +++
man/dropNamed.Rd | 26 ++
man/ensureVector.Rd | 31 +++
man/explode.Rd | 28 +++
man/extractSubList.Rd | 46 ++++
man/filterNull.Rd | 19 ++
man/getAttributeNames.Rd | 22 ++
man/getClass1.Rd | 22 ++
man/getFirst.Rd | 22 ++
man/getMaxIndex.Rd | 33 +++
man/getMaxIndexOfRows.Rd | 49 ++++
man/getOperatingSystem.Rd | 33 +++
man/getRelativePath.Rd | 29 +++
man/getUnixTime.Rd | 15 ++
man/getUsedFactorLevels.Rd | 20 ++
man/hasAttributes.Rd | 24 ++
man/insert.Rd | 33 +++
man/is.error.Rd | 28 +++
man/isDirectory.Rd | 23 ++
man/isEmptyDirectory.Rd | 23 ++
man/isExpensiveExampleOk.Rd | 27 ++
man/isFALSE.Rd | 23 ++
man/isProperlyNamed.Rd | 24 ++
man/isScalarNA.Rd | 19 ++
man/isScalarValue.Rd | 50 ++++
man/isSubset.Rd | 27 ++
man/isSuperset.Rd | 27 ++
man/isValidName.Rd | 25 ++
man/itostr.Rd | 31 +++
man/lib.Rd | 27 ++
man/load2.Rd | 42 ++++
man/lsort.Rd | 18 ++
man/makeDataFrame.Rd | 43 ++++
man/makeFileCache.Rd | 24 ++
man/makeProgressBar.Rd | 91 +++++++
man/makeS3Obj.Rd | 25 ++
man/makeSimpleFileLogger.Rd | 34 +++
man/mapValues.Rd | 52 ++++
man/messagef.Rd | 26 ++
man/namedList.Rd | 27 ++
man/names2.Rd | 33 +++
man/nin.Rd | 19 ++
man/normalize.Rd | 58 +++++
man/optimizeSubInts.Rd | 40 +++
man/pause.Rd | 12 +
man/printStrToChar.Rd | 27 ++
man/printToChar.Rd | 28 +++
man/rangeVal.Rd | 24 ++
man/requirePackages.Rd | 59 +++++
man/rowLapply.Rd | 50 ++++
man/save2.Rd | 41 +++
man/seq_row.Rd | 28 +++
man/setAttribute.Rd | 28 +++
man/setClasses.Rd | 25 ++
man/setRowNames.Rd | 28 +++
man/setValue.Rd | 25 ++
man/sortByCol.Rd | 29 +++
man/splitPath.Rd | 22 ++
man/splitTime.Rd | 30 +++
man/stopf.Rd | 30 +++
man/strrepeat.Rd | 28 +++
man/suppressAll.Rd | 27 ++
man/symdiff.Rd | 22 ++
man/system3.Rd | 36 +++
man/toRangeStr.Rd | 32 +++
man/vlapply.Rd | 39 +++
man/warningf.Rd | 32 +++
man/which.first.Rd | 32 +++
src/getMaxColRowIndex.c | 33 +++
src/getMaxColRowIndex.h | 11 +
src/getMaxIndex.c | 58 +++++
src/getMaxIndex.h | 11 +
src/itostr.c | 28 +++
src/itostr.h | 10 +
src/macros.h | 17 ++
src/which_first.c | 49 ++++
src/which_first.h | 11 +
tests/run-all.R | 2 +
tests/testthat/test_addClasses.R | 9 +
tests/testthat/test_asMatrix.R | 78 ++++++
tests/testthat/test_asQuoted.R | 8 +
tests/testthat/test_binPack.R | 31 +++
tests/testthat/test_btwn.R | 10 +
tests/testthat/test_capitalizeStrings.R | 15 ++
tests/testthat/test_checkArg.R | 120 +++++++++
tests/testthat/test_checkListElementClass.R | 12 +
tests/testthat/test_chunk.R | 60 +++++
tests/testthat/test_clipString.R | 11 +
tests/testthat/test_coalesce.R | 18 ++
tests/testthat/test_collapse.R | 7 +
tests/testthat/test_collapsef.R | 5 +
tests/testthat/test_computeMode.R | 21 ++
tests/testthat/test_convertDataFrameCols.R | 35 +++
tests/testthat/test_convertInteger.R | 27 ++
tests/testthat/test_convertListOfRowsToDataFrame.R | 43 ++++
tests/testthat/test_convertMatrixType.R | 7 +
tests/testthat/test_convertRowsToList.R | 60 +++++
tests/testthat/test_convertToShortString.R | 27 ++
tests/testthat/test_dapply.R | 20 ++
tests/testthat/test_directory.R | 22 ++
tests/testthat/test_do.call2.R | 21 ++
tests/testthat/test_dropNamed.R | 36 +++
tests/testthat/test_ensureVector.R | 16 ++
tests/testthat/test_explode.R | 18 ++
tests/testthat/test_extractSubList.R | 64 +++++
tests/testthat/test_factor.R | 7 +
tests/testthat/test_filterNull.R | 8 +
tests/testthat/test_getAttributeNames.R | 10 +
tests/testthat/test_getClass1.R | 11 +
tests/testthat/test_getFirstLast.R | 14 ++
tests/testthat/test_getMaxColRowIndex.R | 72 ++++++
tests/testthat/test_getMaxIndex.R | 42 ++++
tests/testthat/test_getOperatingSystem.R | 10 +
tests/testthat/test_getRelativePath.R | 21 ++
tests/testthat/test_getUnixTime.R | 6 +
tests/testthat/test_getUsedFactorLevels.R | 11 +
tests/testthat/test_hasAttributes.R | 14 ++
tests/testthat/test_insert.R | 13 +
tests/testthat/test_is.subsetsuperset.R | 15 ++
tests/testthat/test_isFALSE.R | 7 +
tests/testthat/test_isProperlyNamed.R | 13 +
tests/testthat/test_isScalarNA.R | 9 +
tests/testthat/test_isScalarValue.R | 32 +++
tests/testthat/test_isValidNames.R | 9 +
tests/testthat/test_is_error.R | 6 +
tests/testthat/test_itostr.R | 17 ++
tests/testthat/test_load2_save2.R | 26 ++
tests/testthat/test_lsort.R | 6 +
tests/testthat/test_makeDataFrame.R | 36 +++
tests/testthat/test_makeProgressBar.R | 50 ++++
tests/testthat/test_makeSimpleFileLogger.R | 33 +++
tests/testthat/test_mapValues.R | 13 +
tests/testthat/test_namedList.R | 10 +
tests/testthat/test_nin.R | 10 +
tests/testthat/test_normalize.R | 73 ++++++
tests/testthat/test_optimizeSubInts.R | 15 ++
tests/testthat/test_printStrToChar.R | 11 +
tests/testthat/test_printToChar.R | 14 ++
tests/testthat/test_printf.R | 37 +++
tests/testthat/test_rangeVal.R | 13 +
tests/testthat/test_requirePackages.R | 28 +++
tests/testthat/test_rowLapply.R | 33 +++
tests/testthat/test_seq.R | 6 +
tests/testthat/test_setAttribute.R | 10 +
tests/testthat/test_setClasses.R | 7 +
tests/testthat/test_setRowColNames.R | 9 +
tests/testthat/test_setValue.R | 11 +
tests/testthat/test_sortByCol.R | 36 +++
tests/testthat/test_splitPath.R | 17 ++
tests/testthat/test_splitTime.R | 21 ++
tests/testthat/test_strrepeat.R | 8 +
tests/testthat/test_suppressAll.R | 14 ++
tests/testthat/test_symdiff.R | 10 +
tests/testthat/test_system3.R | 39 +++
tests/testthat/test_toRangeStr.R | 31 +++
tests/testthat/test_which.first.last.R | 27 ++
292 files changed, 8768 insertions(+), 148 deletions(-)
diff --git a/DESCRIPTION b/DESCRIPTION
new file mode 100644
index 0000000..c533313
--- /dev/null
+++ b/DESCRIPTION
@@ -0,0 +1,32 @@
+Package: BBmisc
+Title: Miscellaneous Helper Functions for B. Bischl
+Description: Miscellaneous helper functions for and from B. Bischl and
+ some other guys at TU Dortmund, mainly for package development.
+Authors at R: c(person("Bernd", "Bischl", email = "bernd_bischl at gmx.net",
+ role = c("aut", "cre")), person("Michel", "Lang", email =
+ "michellang at gmail.com", role = "aut"), person("Jakob", "Bossek", email =
+ "jakob.bossek at tu-dortmund.de", role = "aut"), person("Daniel", "Horn",
+ email = "daniel.horn at tu-dortmund.de", role = "aut"), person("Jakob",
+ "Richter", email = "code at jakob-r.de", role = "aut"), person("Dirk", "Surmann",
+ email = "surmann at statistik.tu-dortmund.de", role = "aut"))
+URL: https://github.com/berndbischl/BBmisc
+BugReports: https://github.com/berndbischl/BBmisc/issues
+License: BSD_3_clause + file LICENSE
+Encoding: UTF-8
+Imports: utils, methods, stats, checkmate (>= 1.8.0)
+Suggests: testthat, microbenchmark, codetools
+LazyData: yes
+ByteCompile: yes
+Version: 1.10
+RoxygenNote: 5.0.1
+NeedsCompilation: yes
+Packaged: 2016-07-11 21:52:13 UTC; bischl
+Author: Bernd Bischl [aut, cre],
+ Michel Lang [aut],
+ Jakob Bossek [aut],
+ Daniel Horn [aut],
+ Jakob Richter [aut],
+ Dirk Surmann [aut]
+Maintainer: Bernd Bischl <bernd_bischl at gmx.net>
+Repository: CRAN
+Date/Publication: 2016-07-12 07:49:34
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..317fad7
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,3 @@
+YEAR: 2013-2016
+COPYRIGHT HOLDER: Bernd Bischl, Michel Lang, Olaf Mersmann
+ORGANIZATION: TU Dortmund University
diff --git a/MD5 b/MD5
new file mode 100644
index 0000000..b854d46
--- /dev/null
+++ b/MD5
@@ -0,0 +1,280 @@
+7f04456c01086283ae78d2a9229ee413 *DESCRIPTION
+7386455b2e450986702039704e0fb450 *LICENSE
+ccf9ccf74832d34a66cdd556bd6c1fdd *NAMESPACE
+cc5be62c141bb87446789fc76e82405a *NEWS
+c95ee93ae6e1cc3d139e16f1a1c485f9 *R/FileCache.R
+37649421ad19b638a665553cd24b0745 *R/addClasses.R
+a19fab5e53b23926efcf64953f49bf40 *R/argsAsNamedList.R
+3d8824dab593e1f1647d850e94cc1cc5 *R/asMatrix.R
+05e6ba9ccfb6be15b97ed2cdfd97d9a4 *R/asQuoted.R
+102a6bb72d8210fb80b45f4515c01cc3 *R/binPack.R
+88faf131b900a83f9c0c85620488b786 *R/btwn.R
+56df88099f262e40fd104594a2c7731f *R/capitalizeStrings.R
+40a799be55e2562f2b188eeb2cd63ff2 *R/catf.R
+953550836992d4cd19b1661c8c74bb03 *R/checkArg.R
+607b3b87c142d997f15f1d34eb96c0bb *R/checkListElementClass.R
+a7c0552b6aa7d2c1691d82cff4485376 *R/chunk.R
+48f916754d922673ab8f2ec2918109d9 *R/clipString.R
+956e3cfd733539748a02c213def678e2 *R/coalesce.R
+6474806e25c753e2e6d38ed2e2b83cd0 *R/collapse.R
+f19ea97de980e17af2cfdd33eb572801 *R/collapsef.R
+d796fa44ef59e09f21731b72287ed143 *R/computeMode.R
+6182369f5487ee733e9ddb638adcb064 *R/convertDataFrameCols.R
+3127c59099d3f0831d425831e0a017bb *R/convertInteger.R
+2dc25130974b33de32138bfae346c6fa *R/convertListOfRowsToDataFrame.R
+25cbea8b92cd9c71359abe1de6aba3e3 *R/convertMatrixType.R
+0aa7f94d326d17433e3ca503881f5bf4 *R/convertRowsToList.R
+a768bf8674db3d5d83d5c5a26c83f4c8 *R/convertToShortString.R
+a248fcb5e54b59f424197c693ed75253 *R/dapply.R
+dfb0e871e12fc0492300a86736ccdcf4 *R/directory.R
+a92a461f1665ac3fe620d1f4e9066662 *R/do.call2.R
+d15bb0426abfc93d43a20f5b8d8b543c *R/dropNamed.R
+49cd376e7333baa103869d9655b6ec20 *R/ensureVector.R
+ec76a08226506c0a516855fc2fc298b6 *R/explode.R
+e9fcae1462308da4ad61b4acc4d0aa5f *R/extractSubList.R
+96f106167198d3d08d87cfb050eaf48e *R/factor.R
+ed1f7d50dc0893c6e1973f34e344ce5f *R/filterNull.R
+7391eef2300a2da2c6c5e2178b1f9b10 *R/getAttributeNames.R
+263e6489983e592d783815becbd3912c *R/getClass1.R
+a8a2859a4953fcbfefcbdeae4d1cb345 *R/getFirstLast.R
+bd60735efe4a46064ca0276fc44830ff *R/getMaxColIndex.R
+58010b87a6888d602cc01980b04bf411 *R/getMaxIndex.R
+e3a5d3c9ed3fa73f1fea676c8c128c44 *R/getOperatingSystem.R
+be6b3175d3a59a13cec139f078340cc5 *R/getRelativePath.R
+9e51abee4abe6e78930245bc9c4b1aaa *R/getUnixTime.R
+eda7e9ed2c68a2d7f218da52ca03f1c9 *R/getUsedFactorLevels.R
+a0f5b1a871b4deb857a25a12d25ef9af *R/hasAttributes.R
+9af311fcfd2688804b59409284c4a51f *R/insert.R
+ff164b48892cf737901f89f2506176d2 *R/isExpensiveExampleOk.R
+bf3ade174d8e61f3594cf62d21c71ee2 *R/isFALSE.R
+fce55c76d787eedb831731d220ca694c *R/isProperlyNamed.R
+253fcbcdec66ca00e46c93a15137f8d9 *R/isScalarNA.R
+4f4b24c1a3df9bf0b590444d5110cf65 *R/isScalarValue.R
+acd3b0539bf5f9c534fefad0e353c951 *R/isSubset.R
+5e3211824cff133ea45daa09695ec7d6 *R/isSuperset.R
+c84c482db819d69e975c317b069ed33f *R/isValidName.R
+689de2012cdfb03cf98fa827f43b598f *R/is_error.R
+630d0db83c085c1e106da9f5158660ab *R/itostr.R
+b1889a315d4c67abf957656bafc4edfb *R/lib.R
+0f7bf8cb1feaad3dc90a34268e79ae9f *R/load2.R
+64959e639392429ee334776b490b6c41 *R/lsort.R
+692df0b72f047ddc3c9de85af99acb0e *R/makeDataFrame.R
+ca0e4b8b642961b4d3d095fd5e9037c6 *R/makeProgressBar.R
+3005179353ae8a3fe527e2f4d4e4c5a3 *R/makeS3Obj.R
+e4c87c84ca1820b2645dd8ba1447bcf6 *R/makeSimpleFileLogger.R
+f4549d2b6ab7380fae0734c9ca4e72f5 *R/mapValues.R
+a08101a5130a04405545295a434f234f *R/matchDataFrameSubset.R
+1d93558247bae14825e63544d8567985 *R/messagef.R
+bbea4b5fddb93dab9e4d7ccd467fbef6 *R/namedList.R
+d7a212dac2515883b8b947f3139e7fcd *R/names2.R
+a75f48f5cc0bff7e3774951c276ee775 *R/nin.R
+ef042ba4a544e8dee75edea118113ee1 *R/normalize.R
+de8e6cb465cdd3dd19321cf6ac213d2b *R/optimizeSubInts.R
+599ace969590b37f3c2c88b14c57d762 *R/pause.R
+b6fd8274f38b9b99c0a742154598717a *R/printStrToChar.R
+92bfd135c7de27f135e7823996aff04d *R/printToChar.R
+971a824767489aa432bf9ca2e4f60e88 *R/rangeVal.R
+712c07327f88989c242a613868182f8b *R/requirePackages.R
+df031beadf86dfad62057678370d79e6 *R/rowLapply.R
+61b3f7eb6ba48b339e4804f187fd0e0a *R/save2.R
+9d0fa892ba445da469e2435b5d5179f0 *R/seq.R
+6b347cefb473fea607bf9af5be420ae0 *R/setAttribute.R
+2acffcac7efdd8e66123845d7f8c5561 *R/setClasses.R
+0b7ef0cf6e2e01f86d415466f20694a7 *R/setRowColNames.R
+22f9f125514f88a63042233ccfa1d19d *R/setValue.R
+d61551ae970e45f78f8169b719228053 *R/sortByCol.R
+d42215dccfaba5b1d30b11d772c64c69 *R/splitPath.R
+ceb0f1641b1efe0528c6bba833096ded *R/splitTime.R
+a3fba36734928b83ac39e5e5ae093c3c *R/stopf.R
+d5ebd95cd601d2249b07774e7ff1248b *R/strrepeat.R
+18366c8a042dd38325703588bd0918f3 *R/suppressAll.R
+75d4e5b8748b3aa4b47ae024bc8e2d5c *R/symdiff.R
+16a78f0352852bc51d2beb9780a8d299 *R/system3.R
+8fe792f0f54874f8607bc63dd740c9f7 *R/toRangeStr.R
+8e123e02d9fe45608f598d7e3fac94a9 *R/vapply.R
+66e3373494a99d89cf6dacad42149edb *R/warningf.R
+1fe4c8b9e67056c6b1787a4e5d320dba *R/which.first.R
+9db98a4c3deb05ca23f6139604c794e7 *R/zzz.R
+7d9630f2dc37f2231c41816527f84a59 *R/zzz_deprecated.R
+6c28e23a9ee33395fb45fc19114cb26e *man/addClasses.Rd
+85cf6c5b5efcabe05cc8260c1460245f *man/argsAsNamedList.Rd
+7be55e4c70ef62a0cda1757e06eaf467 *man/asMatrixCols.Rd
+16349c85ef00afcd0ad77736c2077f5a *man/asQuoted.Rd
+7b4571d7c1d82da7ec431613cce6850f *man/binPack.Rd
+fdca94ba02a32deca58ad35251456133 *man/btwn.Rd
+976ed6fc3fad483006b818710dd45286 *man/cFactor.Rd
+6ed86f1c9e66d0940d7151d492118dd9 *man/capitalizeStrings.Rd
+ed3d33f51d96103c2ec07f2574bad2a9 *man/catf.Rd
+8b5ca1458a0326e6252d74dd1a0c254b *man/checkArg.Rd
+355651c0810deac8da4a623247268107 *man/checkListElementClass.Rd
+ed1d51f496879bb54c564b7654182c87 *man/chunk.Rd
+fd3921e0da60adc117341d1094f588f9 *man/clipString.Rd
+ecd1ccb7fd6e4ba6f00fbd3ab891789c *man/coalesce.Rd
+6f2baa7edbc662353bb9c3213123141d *man/collapse.Rd
+b558e5ac90f6d7d1406b13f3138ffb76 *man/collapsef.Rd
+621e69a40369c775d1c6e5ef7f44de48 *man/computeMode.Rd
+f8d7492cf45ea2c39432171c43116dff *man/convertDataFrameCols.Rd
+2708b65e90936066674d398bce7e829c *man/convertInteger.Rd
+b61a0cc0163e8716dfb390635049dda4 *man/convertIntegers.Rd
+c0f1a10fc0b9810c5957008b1515042b *man/convertListOfRowsToDataFrame.Rd
+707ebae4c6576b07a5b82bf6dcf5fdf0 *man/convertMatrixType.Rd
+92378bffb4926f0cdf0b85ca75e06c81 *man/convertRowsToList.Rd
+a8692024ce85cbe225ac3ee00836552c *man/convertToShortString.Rd
+99084a0e97a9a2469bc770e22707a809 *man/dapply.Rd
+cc24024f295ef352113c19230f93d04d *man/deprecated.Rd
+964684cd29306a03770f99737063b844 *man/do.call2.Rd
+0bd727a23a077c1ed3a578dec7fd6f72 *man/dropNamed.Rd
+6800348de281bca9f6eb9946bbb6bf30 *man/ensureVector.Rd
+1b61610ad6fe1975e02cb50b6b162884 *man/explode.Rd
+3357bef2ea30da934391546454f187f4 *man/extractSubList.Rd
+2aafaf931dd6640c7700694c53b8bdc1 *man/filterNull.Rd
+803459a58003642e781eea8ac798440c *man/getAttributeNames.Rd
+e1e6a2023c12bc332a3c9a0a64c6801c *man/getClass1.Rd
+e4b68b19f5b651cdd80946a4d12c1086 *man/getFirst.Rd
+e1424b0e53724d037142c00e791004b3 *man/getMaxIndex.Rd
+b90f6d3e901454606780b4c1d023f280 *man/getMaxIndexOfRows.Rd
+e8954aa148674246b103f64dca2ced64 *man/getOperatingSystem.Rd
+1709f1853a8e4931e6c6b97be6f71e52 *man/getRelativePath.Rd
+6b0664caf017c404b98bdd879ce20a5b *man/getUnixTime.Rd
+91eb85f9216d302e0a387317c9eddda4 *man/getUsedFactorLevels.Rd
+1ea0bdf0839cd36584c1190edfcf3288 *man/hasAttributes.Rd
+51f57f27f947986f3c93481a6368c2fb *man/insert.Rd
+2bcbb0fdbeac918c13dcaaf810644dff *man/is.error.Rd
+f61d595ea61102ed6a00fc633edd6f40 *man/isDirectory.Rd
+1d865e2ffd8740adeacc3c6c965d0d2a *man/isEmptyDirectory.Rd
+81ee17e9f37134d13c746a440131e910 *man/isExpensiveExampleOk.Rd
+8f6cecb20c7400a2d8528fb061608004 *man/isFALSE.Rd
+365a676e6689dff611d4e7a010c881fe *man/isProperlyNamed.Rd
+a181bd667a7fc0823633ea38700d2f6c *man/isScalarNA.Rd
+2967b168252db866c2fb1c88f1beea2a *man/isScalarValue.Rd
+3b054825c728efd77102723073a104b5 *man/isSubset.Rd
+2b72056638119c0e39b2a40d539097f8 *man/isSuperset.Rd
+0ea08880a8e1f689adbf7949822de67a *man/isValidName.Rd
+90651aa0abd758e0719876345578989b *man/itostr.Rd
+0e2258daf21d6742bff3fad2301e7393 *man/lib.Rd
+f0e3591c35a727e1f7124749f0e1c223 *man/load2.Rd
+d666f370595b8201acabe915284e9a16 *man/lsort.Rd
+7fefd75e404e58eaccd3d6ba1948ebf4 *man/makeDataFrame.Rd
+6384cbfc1f740aec555280a9e86135bb *man/makeFileCache.Rd
+a7757aca00e5a02f9ab16dce645824b4 *man/makeProgressBar.Rd
+03e65bca043ff0713d9ff022190eda08 *man/makeS3Obj.Rd
+395ac5de54a241f43f40fa3d2b5999a0 *man/makeSimpleFileLogger.Rd
+d1b6375176f615d5b5aa4215bda759e6 *man/mapValues.Rd
+0a46b540e78515f5a77653a62829f9ff *man/messagef.Rd
+a60bf8dbf615aaf0c6fb8a9f2f2c989f *man/namedList.Rd
+ecbd929d52368597f0c8c49ad10b77e6 *man/names2.Rd
+fbf72ffa7e7762bdae07c4b50006414d *man/nin.Rd
+0a6c7cc987466c8c734428b493d7fb7e *man/normalize.Rd
+ea2836d3125adcc379acb0d265dcfd43 *man/optimizeSubInts.Rd
+1551f867d369e1aedbc1e7ace9644ea1 *man/pause.Rd
+837250e6548dd68ea6b70cacc14fec50 *man/printStrToChar.Rd
+db2e6fd69ea5a80b32776c6cc090482e *man/printToChar.Rd
+67fb568acdd5918ab7c50461560fce79 *man/rangeVal.Rd
+94142554a8388dc5c436def74e2bc979 *man/requirePackages.Rd
+ac6cc5e47f488c9a782179a31d2dad7e *man/rowLapply.Rd
+9b4c4e14d420bf43da63a51cec671da5 *man/save2.Rd
+28157848c96897deeada64e8128e8a35 *man/seq_row.Rd
+06eb68e6d21da37f3a59df09bc288c77 *man/setAttribute.Rd
+6b8930c78376d505b801b31016c87c54 *man/setClasses.Rd
+fd408b34c1a43915b3c2ba078f267548 *man/setRowNames.Rd
+5a67e663dc42593c5f08ffab26cf855e *man/setValue.Rd
+b136b58c5445ecf67535a675f58f2f5f *man/sortByCol.Rd
+d1f1611fb69f21ee73edc10cd5fb7888 *man/splitPath.Rd
+578271e955afaf5c48336b919f16d49d *man/splitTime.Rd
+3641096790c2e1d1b2e1ac335b15138f *man/stopf.Rd
+54042026ba220e537fbfdd7d3069b830 *man/strrepeat.Rd
+74d6178ea98ca0d0c9f0f8ea1033375a *man/suppressAll.Rd
+61acd2fd22e2d27749bd9e3e8e33a409 *man/symdiff.Rd
+35d6ba8cfd84456e13db37ce9fa3f8fc *man/system3.Rd
+f698231892cc5a45ef5174fad55c80db *man/toRangeStr.Rd
+64b79c04a4b213bfe5279f1ea39afb2b *man/vlapply.Rd
+0949e18ab83d7d8cb3759de70b668f3b *man/warningf.Rd
+7afbd12247784c4fb6fbbc39e5795876 *man/which.first.Rd
+35b942e80b674462ff4f0c26c0c26d7d *src/getMaxColRowIndex.c
+12c0f6eb710ca0bc0b6e4353030258b4 *src/getMaxColRowIndex.h
+872c1ed132a63360b520d7edcb241d61 *src/getMaxIndex.c
+e41e18c0f5bfc66b2ce50da59cb0919c *src/getMaxIndex.h
+83957d4a67abf8f6b3f399b2d3c96cc1 *src/itostr.c
+845d1f74188f0aefe4bab9ec2e0efc3f *src/itostr.h
+6afff632678c787e398d5b43e72241ed *src/macros.h
+c5564af214c7943d5b311033a6dc38e0 *src/which_first.c
+e87b78c885283187d6d8ca3af40c600e *src/which_first.h
+9e8b5bb9c6dc523818d261be802032f5 *tests/run-all.R
+5989b96cdbdb24092fe473cb0ad9ccb4 *tests/testthat/test_addClasses.R
+f6050a65c56c2cc62d111a7cfcfb1e6e *tests/testthat/test_asMatrix.R
+a2ff4b32481c669f4900f19d7d0ed188 *tests/testthat/test_asQuoted.R
+2c789b11011b47f62e1831d197e42c04 *tests/testthat/test_binPack.R
+ce628478a7d2d2a75dd8d10ce5ab187b *tests/testthat/test_btwn.R
+0de7d7a0a6771c56db69b4c69e94b390 *tests/testthat/test_capitalizeStrings.R
+f23335296ae8ad3ed18b01fdbbafee33 *tests/testthat/test_checkArg.R
+2889c8b5c4cff66c5a31b953545c2d86 *tests/testthat/test_checkListElementClass.R
+01e02d684c7188d63a7fc7fccc5220c4 *tests/testthat/test_chunk.R
+e336b47dfd43383a09d279b77e4f96c3 *tests/testthat/test_clipString.R
+665c15097eb4ccf5a456aef168804f6a *tests/testthat/test_coalesce.R
+6cc17f7528f6efdb407230a8c097631a *tests/testthat/test_collapse.R
+091934d63a45e3bcf62836821baa462b *tests/testthat/test_collapsef.R
+dd9dc2ccdece4005ed5358ced398cf13 *tests/testthat/test_computeMode.R
+7448827f4c9fabbae92a5864d18f2ac9 *tests/testthat/test_convertDataFrameCols.R
+66258ce1820608dcd2e5616b00e8aad0 *tests/testthat/test_convertInteger.R
+77fdfcaf7252093ae760539337f479fa *tests/testthat/test_convertListOfRowsToDataFrame.R
+330977ab6ed531b93bdad0fcbd8a6533 *tests/testthat/test_convertMatrixType.R
+02bc23580f983e1a98ee7dad92c081fe *tests/testthat/test_convertRowsToList.R
+8422c8f8a2f573c6e361c84e5e5dd61b *tests/testthat/test_convertToShortString.R
+c8ca5f9dc69b06b88f920dad74143ff3 *tests/testthat/test_dapply.R
+2730cd895f1362a22eb2c38fc71a2b66 *tests/testthat/test_directory.R
+ee1696434054a3b1c40ae3ba2b2af9be *tests/testthat/test_do.call2.R
+e8bf0877b50ec0059a0aefb098f1791f *tests/testthat/test_dropNamed.R
+c833f182f3f91bd22b2fc718b664d138 *tests/testthat/test_ensureVector.R
+1733a18def47e4f99263c0ec22a05ae9 *tests/testthat/test_explode.R
+8399154accb6dffa48c7d06c1e69f9ae *tests/testthat/test_extractSubList.R
+5db66dab33cc917d87ccdd03ba721c42 *tests/testthat/test_factor.R
+d457e05b43fd367fcebcfdd08eeafa7c *tests/testthat/test_filterNull.R
+464fbd86c7dfddf98ded924e4ee74bd4 *tests/testthat/test_getAttributeNames.R
+729762bd8e29cb1f33e538d13ca899f4 *tests/testthat/test_getClass1.R
+38e58da0e7a723f99dbba1fbd6120143 *tests/testthat/test_getFirstLast.R
+9d2ca5a6feeaef8f88698c61995808d8 *tests/testthat/test_getMaxColRowIndex.R
+03ab4c90b42903b9c9d6500384249457 *tests/testthat/test_getMaxIndex.R
+6a30e242cbbd9a6b5c1eada247875f8d *tests/testthat/test_getOperatingSystem.R
+6f3259098fab9dfee2e8827ea4d54a30 *tests/testthat/test_getRelativePath.R
+511082684bfa9447f2ffabe4c5ebd25d *tests/testthat/test_getUnixTime.R
+64ce851c25c608ec23c06cb7084ad782 *tests/testthat/test_getUsedFactorLevels.R
+89a0524f502cef22d19ce309b13dbdc0 *tests/testthat/test_hasAttributes.R
+967cd4e4bc9499b37fa142d0e30a76fb *tests/testthat/test_insert.R
+ce0f8715ef6d8850ed9d1a393df860e4 *tests/testthat/test_is.subsetsuperset.R
+24b2b476478d1bba9b4dcd42aea56702 *tests/testthat/test_isFALSE.R
+e682af1a73915859b114dac0648619f7 *tests/testthat/test_isProperlyNamed.R
+fc209c118a8f0f682599c0c41705b1e5 *tests/testthat/test_isScalarNA.R
+96814042a3ab82df5e6294b2d1ae775c *tests/testthat/test_isScalarValue.R
+b9d87c2e03b710fb0340d7325bda8bb2 *tests/testthat/test_isValidNames.R
+1dd894fc227ccd3e6b0f233963d44c3c *tests/testthat/test_is_error.R
+86fd8371f6dec17d19b88de3c8c0e36f *tests/testthat/test_itostr.R
+8663a10c1f2e1e8123a0ef80a7d4824a *tests/testthat/test_load2_save2.R
+0e694eb0d74663edd84258450e4dee18 *tests/testthat/test_lsort.R
+b1ab421f949e43a571b3b65acd96d1b2 *tests/testthat/test_makeDataFrame.R
+1bb67fc1ef119c4e78324bfafe1de1b5 *tests/testthat/test_makeProgressBar.R
+470defa91aab0e97dbccbd931924047c *tests/testthat/test_makeSimpleFileLogger.R
+2181619d625795bb64ba88ce2b84de2d *tests/testthat/test_mapValues.R
+1130be95adf737b30a0c4c783648e973 *tests/testthat/test_namedList.R
+d06ec9a9e27677e23f8a9d8fd030748e *tests/testthat/test_nin.R
+d937f2e0f11346490140f08998bcbff1 *tests/testthat/test_normalize.R
+98a1a85a55a68773c748dab8f4f0ad40 *tests/testthat/test_optimizeSubInts.R
+4ec4fcdd19c7734b29a9107d85c8f4fe *tests/testthat/test_printStrToChar.R
+edc7badddfe9bd1c8fe1fb0a77901d16 *tests/testthat/test_printToChar.R
+77530a85391710d9f2eedd2d9fc87e4c *tests/testthat/test_printf.R
+1442290f39895a964fd1972ed35f7611 *tests/testthat/test_rangeVal.R
+51c5c9322504cfec1c30a37457349912 *tests/testthat/test_requirePackages.R
+c793db23c505860557e166330b21d7ab *tests/testthat/test_rowLapply.R
+296998c0e7d9d6cb8ab0dc4c8c8c4b05 *tests/testthat/test_seq.R
+e6ee1c9a73b327cf0719d69d01ee0afe *tests/testthat/test_setAttribute.R
+52f2657e8983aac7febfa8db35908ab0 *tests/testthat/test_setClasses.R
+4edc08a44f11533fc89463b7dbc18e41 *tests/testthat/test_setRowColNames.R
+7272c751710069de721b9f1b7151730f *tests/testthat/test_setValue.R
+ed895ae818a488ce37d14fe377ce328b *tests/testthat/test_sortByCol.R
+4d6d80bc21cf4aefea95b86e00ae05e3 *tests/testthat/test_splitPath.R
+b865603ba3d7e6bb224d1cf4a388e0d0 *tests/testthat/test_splitTime.R
+e9b339c5e397f2b7f8487aacc08d9d47 *tests/testthat/test_strrepeat.R
+42901946d8b28526e57dd7cd37b81d7e *tests/testthat/test_suppressAll.R
+c43ce1a7fe74b064b67a90b8aa1ba77f *tests/testthat/test_symdiff.R
+f6c99819004299fe7d625f9c49117379 *tests/testthat/test_system3.R
+c60f155f7f164f9f776a9256f3b99f70 *tests/testthat/test_toRangeStr.R
+f12081b0ea79bdef678265bffbf6f90c *tests/testthat/test_which.first.last.R
diff --git a/NAMESPACE b/NAMESPACE
new file mode 100644
index 0000000..eac4eb6
--- /dev/null
+++ b/NAMESPACE
@@ -0,0 +1,131 @@
+# Generated by roxygen2: do not edit by hand
+
+S3method(normalize,data.frame)
+S3method(normalize,matrix)
+S3method(normalize,numeric)
+export("%btwn%")
+export("%nin%")
+export(addClasses)
+export(argsAsNamedList)
+export(asMatrixCols)
+export(asMatrixRows)
+export(asQuoted)
+export(binPack)
+export(cFactor)
+export(capitalizeStrings)
+export(catf)
+export(checkArg)
+export(checkListElementClass)
+export(chunk)
+export(clipString)
+export(coalesce)
+export(collapse)
+export(collapsef)
+export(computeMode)
+export(convertColsToList)
+export(convertDataFrameCols)
+export(convertDfCols)
+export(convertInteger)
+export(convertIntegers)
+export(convertListOfRowsToDataFrame)
+export(convertMatrixType)
+export(convertRowsToList)
+export(convertToShortString)
+export(dapply)
+export(do.call2)
+export(dropNamed)
+export(ensureVector)
+export(explode)
+export(extractSubList)
+export(filterNull)
+export(getAttributeNames)
+export(getClass1)
+export(getFirst)
+export(getLast)
+export(getMaxIndex)
+export(getMaxIndexOfCols)
+export(getMaxIndexOfRows)
+export(getMinIndex)
+export(getMinIndexOfCols)
+export(getMinIndexOfRows)
+export(getOperatingSystem)
+export(getRelativePath)
+export(getUnixTime)
+export(getUsedFactorLevels)
+export(hasAttributes)
+export(insert)
+export(is.error)
+export(isDarwin)
+export(isDirectory)
+export(isEmptyDirectory)
+export(isExpensiveExampleOk)
+export(isFALSE)
+export(isLinux)
+export(isProperlyNamed)
+export(isScalarCharacter)
+export(isScalarComplex)
+export(isScalarFactor)
+export(isScalarInteger)
+export(isScalarLogical)
+export(isScalarNA)
+export(isScalarNumeric)
+export(isScalarValue)
+export(isSubset)
+export(isSuperset)
+export(isUnix)
+export(isValidName)
+export(isWindows)
+export(itostr)
+export(lib)
+export(listToShortString)
+export(load2)
+export(lsort)
+export(makeDataFrame)
+export(makeFileCache)
+export(makeProgressBar)
+export(makeS3Obj)
+export(makeSimpleFileLogger)
+export(mapValues)
+export(messagef)
+export(namedList)
+export(names2)
+export(normalize)
+export(optimizeSubInts)
+export(pause)
+export(printStrToChar)
+export(printToChar)
+export(rangeVal)
+export(requirePackages)
+export(rowLapply)
+export(rowSapply)
+export(save2)
+export(seq_col)
+export(seq_row)
+export(setAttribute)
+export(setClasses)
+export(setColNames)
+export(setRowNames)
+export(setValue)
+export(sortByCol)
+export(splitPath)
+export(splitTime)
+export(stopf)
+export(strrepeat)
+export(suppressAll)
+export(symdiff)
+export(system3)
+export(toRangeStr)
+export(vcapply)
+export(viapply)
+export(vlapply)
+export(vnapply)
+export(warningf)
+export(which.first)
+export(which.last)
+import(checkmate)
+import(stats)
+import(utils)
+importFrom(methods,is)
+useDynLib(BBmisc,c_getMaxIndex)
+useDynLib(BBmisc,c_getMaxIndexOfCols)
+useDynLib(BBmisc,c_getMaxIndexOfRows)
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..b4ae9c9
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,156 @@
+BBmisc_1.10:
+- New argument min.versions for requirePackages
+
+BBmisc_1.9: 2015-02-03
+- New argument .newline for messagef
+- requirePackages can now dispatch to requireNamespace and has argument default.method.
+- normalize now also handles NAs
+
+- new functions
+-- mapValues
+
+
+BBmisc_1.8: 2014-10-30
+- Options for the ProgressBar can now be directly passed to the constructor.
+- Fixed smaller bugs in normalize
+
+- new functions
+-- itostr
+-- getRelativePath
+-- splitPath
+-- do.call2
+
+BBmisc_1.7: 21-Jun-2014
+- extractSubList allows for repeated indexing
+
+- new functions:
+-- asQuoted
+-- collapsef
+-- ensureVector
+-- explode
+-- getAttributeNames
+-- getClass1
+-- getUsedFactorLevels
+-- hasAttributes
+-- isSubset, isSuperset
+-- makeFileCache
+-- normalize
+-- setValue
+-- optimizeSubInts
+
+BBmisc_1.6: 23-Apr-2014
+- the ProgressBar now outputs to stderr by default. But the stream can be configured.
+- improve handling of result names (row.names and col.names) in some functions a bit
+- convertRowsToList now converts matrices into list of vector by default (see new arg "as.vector")
+- rename first, last to which.first, which.last
+- improved extractSubList and rowSapply a bit,
+ simplification to matrix can be stated in a more readable way.
+- new functions:
+-- operator %btwn%.
+-- convertListOfRowsToDataFrame
+-- convertMatrixType
+-- convertColsToList
+-- v*apply type of functions
+-- dapply
+-- rangeVal
+-- getFirst, getLast
+-- symdiff
+-- asMatrixCols, asMatrixRows
+-- isScalar<Type> family of helper functions
+-- sortByCol
+
+BBmisc_1.5: 25-Jan-2014
+- removed stringsAsFactors, use convertDataFrameCols
+- removed convertDfCols, use convertDataFrameCols
+- removed listToShortString, use convertToShortString
+- new functions:
+-- dropNamed
+-- first, last
+-- binPack
+-- isValidName
+
+BBmisc_1.4: 06-Nov-2013
+- renamed convertDfCols to convertDataFrameCols
+- deprecated listToShortString, use convertToShortString
+- deprecated stringsAsFactors, use convertDataFrameCols
+- chunk distributes size of chunks in a better way
+- new functions:
+-- makeS3Obj
+-- getMaxIndex, getMinIndex
+-- getMaxIndexOfRows, getMinIndexOfRows, getMaxIndexOfCols, getMinIndexOfCols
+-- toRangeStr
+-- getOperatingSystem, isWindows, isUnix, isLinux, isDarwin
+-- clipString
+-- getUnixTime
+-- isScalarValue
+-- makeDataFrame
+-- convertToShortString
+-- convertRowsToList
+
+BBmisc_1.3-64: 20-Aug-2013
+- removed parallelMap et al., this is now hosted in an extra package at:
+ https://github.com/berndbischl/parallelMap
+- bugfix for checkArg, lower/upper only checked first element
+- exta argument "missing.val" for names2
+- extra argument "logicals.as.factor" for convertDFCols
+- some speed improvements for convertDFCols and notin
+- is.error also works now for objects of class "error" and not only "try-error"
+- new functions:
+-- isDirectory
+-- rowLapply, rowSapply
+-- setAttribute
+-- seq_row, seq_col
+-- strrepeat
+-- makeSimpleFileLogger
+-- isScalarNA
+-- pause
+-- printStrToChar
+
+BBmisc_1.2-200: 02-May-2013
+- checkArg can now test whether arg is one of multiple classes (OR disjunctive)
+- bug fix: cpus setting was not properly respected in multicore mode
+- bug fix: warnings where not turned into errors with warningf and option(warn=2)
+- some minor bug fixes
+- parallelMap: switched multicore mode to package parallel
+- new functions
+-- lib
+-- argsAsNamedList
+-- names2
+-- convertDfCols
+
+BBmisc_1.1-166: 16-Nov-2012
+- some small fixes and added arguments
+- new functions:
+-- setRowNames, setColNames
+-- setClasses, addClasses
+-- isFALSE
+-- lsort
+-- computeMode
+
+BBmisc_1.1-132: 04-Jul-2012
+- removed regmatches dependency
+
+BBmisc_1.1-125: 10-May-2012
+- removed stringr dependency
+- new interface for ProgressBar and more therefore more functionality
+- some global options for progressbar behaviour
+- options immediate and warning.length for warningf
+- checkListElementClass now first checks that argument is a list
+- nin (notin) operator
+- parallelMap function, can delegate to multicore or snowfall
+- stringsAsFactors
+- system3
+- load2
+
+BBmisc_1.0-77: 17-Mar-2012
+- removed calls to .Internal
+- more examples
+- fixed a bug in checkArg
+- makeProgressbar: new option 'inc' to increment
+- stopf: new option warning.length
+- more options for requirePackages
+- new functions: chunk, isExpensiveExampleOk
+
+BBmisc_1.0-58: 05-Jan-2012
+- First submit to CRAN.
+
diff --git a/R/FileCache.R b/R/FileCache.R
new file mode 100644
index 0000000..f5a4b92
--- /dev/null
+++ b/R/FileCache.R
@@ -0,0 +1,26 @@
+#' A caching wrapper around load2.
+#'
+#' This closure returns a wrapper around \code{\link{load2}} which per
+#' default caches loaded objects and returns the cached version
+#' in subsequent calls.
+#'
+#' @param use.cache [\code{logical(1)}]\cr
+#' Enable the cache?
+#' Default is \code{TRUE}.
+#' @return [\code{function()}] with argument \code{slot}
+#' (name of the slot to cache the object in, default is \dQuote{default}).
+#' All other arguments are passed down to \code{\link{load2}}.
+#' @export
+makeFileCache = function(use.cache = TRUE) {
+ assertFlag(use.cache)
+ .cache = list()
+
+ function(file, slot = "default", ...) {
+ if (use.cache) {
+ if (is.null(.cache[[slot]]) || .cache[[slot]]$file != file)
+ .cache[[slot]] = list(file = file, obj = load2(file = file, ...))
+ return(.cache[[slot]]$obj)
+ }
+ return(load2(file = file, ...))
+ }
+}
diff --git a/R/addClasses.R b/R/addClasses.R
new file mode 100644
index 0000000..652652c
--- /dev/null
+++ b/R/addClasses.R
@@ -0,0 +1,15 @@
+
+#' A wrapper to add to the class attribute.
+#'
+#' @param x [any]\cr
+#' Your object.
+#' @param classes [\code{character}]\cr
+#' Classes to add. Will be added in front (specialization).
+#' @return Changed object \code{x}.
+#' @export
+#' @examples
+#' addClasses(list(), c("foo1", "foo2"))
+addClasses = function(x, classes) {
+ class(x) = c(classes, class(x))
+ x
+}
diff --git a/R/argsAsNamedList.R b/R/argsAsNamedList.R
new file mode 100644
index 0000000..8698253
--- /dev/null
+++ b/R/argsAsNamedList.R
@@ -0,0 +1,22 @@
+#' Parses \code{...} arguments to a named list.
+#'
+#' The deparsed name will be used for arguments with missing names.
+#' Missing names will be set to \code{NA}.
+#'
+#' @param ...
+#' Arbitrary number of objects.
+#' @return [\code{list}]: Named list with objects.
+#' @export
+#' @examples
+#' z = 3
+#' argsAsNamedList(x = 1, y = 2, z)
+argsAsNamedList = function(...) {
+ args = list(...)
+ ns = names2(args)
+ ns.missing = is.na(ns)
+ if (any(ns.missing)) {
+ ns.sub = as.character(substitute(deparse(...)))[-1L]
+ ns[ns.missing] = ns.sub[ns.missing]
+ }
+ setNames(args, replace(ns, ns %in% c("NA", "NULL", ""), NA_character_))
+}
diff --git a/R/asMatrix.R b/R/asMatrix.R
new file mode 100644
index 0000000..670fbab
--- /dev/null
+++ b/R/asMatrix.R
@@ -0,0 +1,43 @@
+#' Extracts a named element from a list of lists.
+#'
+#' @param xs [\code{list}]\cr
+#' A list of vectors of the same length.
+#' @param row.names [\code{character} | \code{integer} | \code{NULL}]\cr
+#' Row names of result.
+#' Default is to take the names of the elements of \code{xs}.
+#' @param col.names [\code{character} | \code{integer} | \code{NULL}]\cr
+#' Column names of result.
+#' Default is to take the names of the elements of \code{xs}.
+#' @return [\code{matrix}].
+#' @export
+asMatrixCols = function(xs, row.names, col.names) {
+ assertList(xs)
+ n = length(xs)
+ if (n == 0L)
+ return(matrix(0, nrow = 0L, ncol = 0L))
+ assertList(xs, types = "vector")
+
+ m = unique(viapply(xs, length))
+ if (length(m) != 1L)
+ stopf("Vectors must all be of the same length!")
+
+ if (missing(row.names)) {
+ row.names = names(xs[[1L]])
+ }
+
+ if (missing(col.names)) {
+ col.names = names(xs)
+ }
+
+ xs = unlist(xs)
+ dim(xs) = c(m, n)
+ rownames(xs) = row.names
+ colnames(xs) = col.names
+ return(xs)
+}
+
+#' @rdname asMatrixCols
+#' @export
+asMatrixRows = function(xs, row.names, col.names) {
+ t(asMatrixCols(xs, row.names = col.names, col.names = row.names))
+}
diff --git a/R/asQuoted.R b/R/asQuoted.R
new file mode 100644
index 0000000..a713f34
--- /dev/null
+++ b/R/asQuoted.R
@@ -0,0 +1,18 @@
+#' Converts a string into a quoted expression.
+#'
+#' Works the same as if you would have entered the expression and called
+#' \code{\link{quote}} on it.
+#'
+#' @param s [\code{character(1)}]\cr
+#' Expression as string.
+#' @param env [\code{numeric(1)}]\cr
+#' Environment for expression.
+#' Default is \code{parent.frame()}
+#' @return Quoted expression.
+#' @export
+#' @examples
+#' asQuoted("x == 3")
+asQuoted = function(s, env = parent.frame()) {
+ assertString(s)
+ structure(parse(text = s)[1L], env = env, class = "quoted")[[1L]]
+}
diff --git a/R/binPack.R b/R/binPack.R
new file mode 100644
index 0000000..8966908
--- /dev/null
+++ b/R/binPack.R
@@ -0,0 +1,53 @@
+#' Simple bin packing.
+#'
+#' Maps numeric items in \code{x} into groups with sum
+#' less or equal than \code{capacity}.
+#' A very simple greedy algorithm is used, which is not really optimized
+#' for speed. This is a convenience function for smaller vectors, not
+#' a competetive solver for the real binbacking problem.
+#' If an element of \code{x} exceeds \code{capacity}, an error
+#' is thrown.
+#'
+#' @param x [\code{numeric}]\cr
+#' Numeric vector of elements to group.
+#' @param capacity [\code{numeric(1)}]\cr
+#' Maximum capacity of each bin, i.e., elements will be grouped
+#' so their sum does not exceed this limit.
+#' @return [\code{integer}]. Integer with values \dQuote{1} to \dQuote{n.bins}
+#' indicating bin membership.
+#' @export
+#' @examples
+#' x = 1:10
+#' bp = binPack(x, 11)
+#' xs = split(x, bp)
+#' print(xs)
+#' print(sapply(xs, sum))
+binPack = function(x, capacity) {
+ assertNumeric(x, min.len = 1L, lower = 0, any.missing = FALSE)
+ assertNumber(capacity)
+
+ too.big = which.first(x > capacity, use.names = FALSE)
+ if (length(too.big))
+ stopf("Capacity not sufficient. Item %i (x=%f) does not fit", too.big, x[too.big])
+ if (any(is.infinite(x)))
+ stop("Infinite elements found in 'x'")
+
+ ord = order(x, decreasing = TRUE)
+ grp = integer(length(x))
+ sums = vector(typeof(x), 1L)
+ bin.count = 1L
+
+ for(j in ord) {
+ new.sums = sums + x[j]
+ pos = which.first(new.sums <= capacity, use.names = FALSE)
+ if (length(pos)) {
+ grp[j] = pos
+ sums[pos] = new.sums[pos]
+ } else {
+ bin.count = bin.count + 1L
+ grp[j] = bin.count
+ sums[bin.count] = x[j]
+ }
+ }
+ grp
+}
diff --git a/R/btwn.R b/R/btwn.R
new file mode 100644
index 0000000..ffa1009
--- /dev/null
+++ b/R/btwn.R
@@ -0,0 +1,18 @@
+#' Check if some values are covered by the range of the values in a second vector.
+#'
+#' @param x [\code{numeric(n)}]\cr
+#' Value(s) that should be within the range of \code{y}.
+#' @param y [\code{numeric}]\cr
+#' Numeric vector which defines the range.
+#' @return [\code{logical(n)}]. For each value in \code{x}: Is it in the range of \code{y}?
+#' @usage x \%btwn\% y
+#' @rdname btwn
+#' @examples
+#' x = 3
+#' y = c(-1,2,5)
+#' x %btwn% y
+#' @export
+`%btwn%` = function(x, y) {
+ r = range(y)
+ x <= r[2] & x >= r[1]
+}
diff --git a/R/capitalizeStrings.R b/R/capitalizeStrings.R
new file mode 100644
index 0000000..81c33b8
--- /dev/null
+++ b/R/capitalizeStrings.R
@@ -0,0 +1,43 @@
+#' @title Capitalize strings in a vector
+#'
+#' @description
+#' Capitalise first word or all words of a character vector.
+#' Lower back of vector element or word, respectively.
+#'
+#' @param x [\code{character(n)}]\cr
+#' Vector of character elements to capitalize.
+#' @param all.words [\code{logical(1)}]\cr
+#' If \code{TRUE} all words of each vector element are capitalized.
+#' \code{FALSE} capitalizes the first word of each vector element.
+#' @param lower.back [\code{logical(1)}]\cr
+#' \code{TRUE} lowers the back of each word or vector element (depends on \code{all.words}).
+#' @return Capitalized vector: [\code{character(n)}].
+#' @export
+#' @examples
+#' capitalizeStrings(c("the taIl", "wags The dOg", "That looks fuNny!"))
+#' capitalizeStrings(c("the taIl", "wags The dOg", "That looks fuNny!")
+#' , all.words = TRUE, lower.back = TRUE)
+capitalizeStrings = function(x, all.words = FALSE, lower.back = FALSE) {
+ assertCharacter(x)
+ assertLogical(all.words, any.missing = FALSE, len = 1L)
+ assertLogical(lower.back, any.missing = FALSE, len = 1L)
+
+ if (all.words) {
+ pattern = "([[:alnum:]])([[:alnum:]]*)"
+ replacement = "\\U\\1"
+ if (lower.back) {
+ replacement = paste0(replacement, "\\L\\2")
+ } else {
+ replacement = paste0(replacement, "\\E\\2")
+ }
+ } else {
+ pattern = "^([[:alnum:]])"
+ replacement = "\\U\\1"
+ if (lower.back) {
+ pattern = paste0(pattern, "(.*)")
+ replacement = paste0(replacement, "\\L\\2")
+ }
+ }
+
+ return(gsub(pattern, replacement, x, perl = TRUE))
+}
diff --git a/R/catf.R b/R/catf.R
new file mode 100644
index 0000000..2f389f4
--- /dev/null
+++ b/R/catf.R
@@ -0,0 +1,23 @@
+#' Wrapper for cat and sprintf.
+#'
+#' A simple wrapper for \code{cat(sprintf(...))}.
+#'
+#' @param ... [any]\cr
+#' See \code{\link{sprintf}}.
+#' @param file [\code{character(1)}]\cr
+#' See \code{\link{cat}}.
+#' Default is \dQuote{}.
+#' @param append [\code{logical(1)}]\cr
+#' See \code{\link{cat}}.
+#' Default is \code{FALSE}.
+#' @param newline [\code{logical(1)}]\cr
+#' Append newline at the end?
+#' Default is \code{TRUE}.
+#' @return Nothing.
+#' @export
+#' @examples
+#' msg = "a message."
+#' catf("This is %s", msg)
+catf = function(..., file = "", append = FALSE, newline = TRUE) {
+ cat(sprintf(...), ifelse(newline, "\n", ""), sep = "", file = file, append = append)
+}
diff --git a/R/checkArg.R b/R/checkArg.R
new file mode 100644
index 0000000..24e39f6
--- /dev/null
+++ b/R/checkArg.R
@@ -0,0 +1,109 @@
+#' Check for a function argument.
+#'
+#' Throws exception if checks are not passed.
+#' Note that argument is evaluated when checked.
+#'
+#' @param x [any]\cr
+#' Argument.
+#' @param cl [\code{character}]\cr
+#' Class that argument must \dQuote{inherit} from.
+#' If multiple classes are given, \code{x} must \dQuote{inherit} from at least one of these.
+#' See also argument \code{s4}.
+#' @param s4 [\code{logical(1)}]\cr
+#' If \code{TRUE}, use \code{is} for checking class \code{cl}, otherwise use \code{\link{inherits}}, which
+#' implies that only S3 classes are correctly checked. This is done for speed reasons
+#' as calling \code{\link{is}} is pretty slow.
+#' Default is \code{FALSE}.
+#' @param len [\code{integer(1)}]\cr
+#' Length that argument must have.
+#' Not checked if not passed, which is the default.
+#' @param min.len [\code{integer(1)}]\cr
+#' Minimal length that argument must have.
+#' Not checked if not passed, which is the default.
+#' @param max.len [\code{integer(1)}]\cr
+#' Maximal length that argument must have.
+#' Not checked if not passed, which is the default.
+#' @param choices [any]\cr
+#' Discrete number of choices, expressed by a vector of R objects.
+#' If passed, argument must be identical to one of these and nothing else is checked.
+#' @param subset [any]\cr
+#' Discrete number of choices, expressed by a vector of R objects.
+#' If passed, argument must be identical to a subset of these and nothing else is checked.
+#' @param lower [\code{numeric(1)}]\cr
+#' Lower bound for numeric vector arguments.
+#' Default is \code{NA}, which means not required.
+#' @param upper [\code{numeric(1)}]\cr
+#' Upper bound for numeric vector arguments.
+#' Default is \code{NA}, which means not required.
+#' @param na.ok [\code{logical(1)}]\cr
+#' Is it ok if a vector argument contains NAs?
+#' Default is \code{TRUE}.
+#' @param formals [\code{character}]\cr
+#' If this is passed, \code{x} must be a function.
+#' It is then checked that \code{formals} are the names of the
+#' (first) formal arguments in the signature of \code{x}.
+#' Meaning \code{checkArg(function(a, b), formals = "a")} is ok.
+#' Default is missing.
+#' @return Nothing.
+#' @export
+#' @examples
+#' x = 1L
+#' checkArg(x, "integer", len = 1, na.ok = FALSE, upper = 3L)
+#' x = as.integer(NA)
+#' checkArg(x, "integer", len = 1, na.ok = TRUE)
+#' x = c("foo", "bar")
+#' checkArg(x, "character")
+#' x = "foo"
+#' checkArg(x, choices = c("foo", "bar"))
+#' x = c("foo", "bar")
+#' checkArg(x, subset = c("foo", "bar"))
+#' fun = function(foo, bar)
+#' checkArg(fun, formals = c("foo", "bar"))
+checkArg = function(x, cl, s4 = FALSE, len, min.len, max.len, choices, subset, lower = NA, upper = NA, na.ok = TRUE, formals) {
+ s = deparse(substitute(x))
+ if (missing(x))
+ stop("Argument ", s, " must not be missing!")
+ cl2 = class(x)[1]
+ len2 = length(x)
+ matchEl = function(x, xs) any(sapply(xs, function(y) identical(y, x)))
+ # choices must be done first
+ if (!missing(choices)) {
+ if (!matchEl(x, choices))
+ stop("Argument ", s, " must be any of: ", collapse(choices), "!")
+ } else if (!missing(subset)) {
+ if (!all(sapply(x, matchEl, xs = subset)))
+ stop("Argument ", s, " must be subset of: ", collapse(subset), "!")
+ } else if (!missing(formals)) {
+ if (!is.function(x))
+ stop("Argument ", s, " must be of class ", "function", " not: ", cl2, "!")
+ fs = names(formals(x))
+ if (length(fs) < length(formals) || !all(formals == fs[seq_along(formals)]))
+ stop("Argument function must have first formal args: ", paste(formals, collapse = ","), "!")
+ } else {
+ mycheck = function(x, cc)
+ if(identical(cc, "numeric"))
+ is.numeric(x)
+ else if(identical(cc, "integer"))
+ is.integer(x)
+ else if(identical(cc, "vector"))
+ is.vector(x)
+ else if (!s4)
+ inherits(x, cc)
+ else if (s4)
+ is(x, cc)
+ if (!any(sapply(cl, mycheck, x = x)))
+ stop("Argument ", s, " must be of class ", collapse(cl, " OR "), ", not: ", cl2, "!")
+ if (!missing(len) && len2 != len)
+ stop("Argument ", s, " must be of length ", len, " not: ", len2, "!")
+ if (!missing(min.len) && len2 < min.len)
+ stop("Argument ", s, " must be at least of length ", min.len, " not: ", len2, "!")
+ if (!missing(max.len) && len2 > max.len)
+ stop("Argument ", s, " must be at most of length ", max.len, " not: ", len2, "!")
+ if (!na.ok && any(is.na(x)))
+ stop("Argument ", s, " must not contain any NAs!")
+ if (is.numeric(x) && !is.na(lower) && ((is.na(x) && !na.ok) || (!is.na(x) && any(x < lower))))
+ stop("Argument ", s, " must be greater than or equal ", lower, "!")
+ if (is.numeric(x) && !is.na(upper) && ((is.na(x) && !na.ok) || (!is.na(x) && any(x > upper))))
+ stop("Argument ", s, " must be less than or equal ", upper, "!")
+ }
+}
diff --git a/R/checkListElementClass.R b/R/checkListElementClass.R
new file mode 100644
index 0000000..9ed04e7
--- /dev/null
+++ b/R/checkListElementClass.R
@@ -0,0 +1,25 @@
+#' Check that a list contains only elements of a required type.
+#'
+#' Check that argument is a list and contains only elements of a required type.
+#' Throws exception if check is not passed.
+#' Note that argument is evaluated when checked.
+#'
+#' @param xs [\code{list}]\cr
+#' Argument.
+#' @param cl [\code{character(1)}]\cr
+#' Class that elements must have. Checked with \code{is}.
+#' @return Nothing.
+#' @export
+#' @examples
+#' xs = as.list(1:3)
+#' checkListElementClass(xs, "numeric")
+checkListElementClass = function(xs, cl) {
+ assertList(xs)
+ s = deparse(substitute(xs))
+ lapply(seq_along(xs), function(i) {
+ x = xs[[i]]
+ if(!(is(x, cl)))
+ stop("List ", s, " has element of wrong type ", class(x)[1L], " at position ", i, ". Should be: ", cl)
+ })
+ invisible(NULL)
+}
diff --git a/R/chunk.R b/R/chunk.R
new file mode 100644
index 0000000..164f2ab
--- /dev/null
+++ b/R/chunk.R
@@ -0,0 +1,72 @@
+#' Chunk elements of vectors into blocks of nearly equal size.
+#'
+#' In case of shuffling and vectors that cannot be chunked evenly,
+#' it is chosen randomly which levels / chunks will receive 1 element less.
+#' If you do not shuffle, always the last chunks will receive 1 element less.
+#'
+#' @param x [ANY]\cr
+#' Vector, list or other type supported by \code{\link[base]{split}}.
+#' @param chunk.size [\code{integer(1)}]\cr
+#' Requested number of elements in each chunk.
+#' Cannot be used in combination with \code{n.chunks} or \code{props}.
+#' If \code{x} cannot be evenly chunked, some chunks will have less elements.
+#' @param n.chunks [\code{integer(1)}]\cr
+#' Requested number of chunks.
+#' If more chunks than elements in \code{x} are requested, empty chunks are
+#' dropped.
+#' Can not be used in combination with \code{chunks.size} or \code{props}.
+#' @param props [\code{numeric}]\cr
+#' Vector of proportions for chunk sizes.
+#' Empty chunks may occur, depending on the length of \code{x} and the given
+#' proportions.
+#' Cannot be used in combination with \code{chunks.size} or \code{n.chunks}.
+#' @param shuffle [\code{logical(1)}]\cr
+#' Shuffle \code{x}?
+#' Default is \code{FALSE}.
+#' @return [unnamed \code{list}] of chunks.
+#' @export
+#' @examples
+#' xs = 1:10
+#' chunk(xs, chunk.size = 3)
+#' chunk(xs, n.chunks = 2)
+#' chunk(xs, n.chunks = 2, shuffle = TRUE)
+#' chunk(xs, props = c(7, 3))
+chunk = function(x, chunk.size, n.chunks, props, shuffle = FALSE) {
+ assertFlag(shuffle)
+ method = c("chunk.size", "n.chunks", "props")
+ method = method[!c(missing(chunk.size), missing(n.chunks), missing(props))]
+ if (length(method) != 1L)
+ stop("You must provide exactly one of 'chunk.size', 'n.chunks' or 'props'")
+ nx = length(x)
+
+ ch = switch(method,
+ chunk.size = {
+ chunk.size = convertInteger(chunk.size)
+ assertCount(chunk.size, positive = TRUE)
+ getNChunks(nx, nx %/% chunk.size + (nx %% chunk.size > 0L), shuffle)
+ },
+ n.chunks = {
+ n.chunks = convertInteger(n.chunks)
+ assertCount(n.chunks, positive = TRUE)
+ getNChunks(nx, n.chunks, shuffle)
+ },
+ props = {
+ assertNumeric(props, min.len = 1L, any.missing = FALSE, lower = 0)
+ props = props / sum(props)
+ ch = factor(rep.int(seq_along(props), round(props * nx, digits = 0L)),
+ levels = seq_along(props))
+ if (shuffle) sample(ch) else ch
+ })
+
+ unname(split(x, ch))
+}
+
+getNChunks = function(nx, n.chunks, shuffle) {
+ n.chunks = min(n.chunks, nx)
+ if (shuffle) {
+ c(sample(seq(0L, (nx %/% n.chunks) * n.chunks - 1L) %% n.chunks),
+ sample(n.chunks, nx %% n.chunks) - 1L)
+ } else {
+ sort(seq.int(0L, nx - 1L) %% n.chunks)
+ }
+}
diff --git a/R/clipString.R b/R/clipString.R
new file mode 100644
index 0000000..d4cefd2
--- /dev/null
+++ b/R/clipString.R
@@ -0,0 +1,22 @@
+#' Shortens strings to a given length.
+#'
+#' @param x [\code{character}]\cr
+#' Vector of strings.
+#' @param len [\code{integer(1)}]\cr
+#' Absolute length the string should be clipped to, including \code{tail}.
+#' Note that you cannot clip to a shorter length than \code{tail}.
+#' @param tail [\code{character(1)}]\cr
+#' If the string has to be shortened at least 1 character, the final characters will be \code{tail}.
+#' Default is \dQuote{...}.
+#' @return [\code{character(1)}].
+#' @export
+#' @examples
+#' print(clipString("abcdef", 10))
+#' print(clipString("abcdef", 5))
+clipString = function(x, len, tail = "...") {
+ assertCharacter(x, any.missing = TRUE)
+ len = asInteger(len, len = 1L, lower = nchar(tail))
+ assertString(tail)
+ ind = (!is.na(x) & nchar(x) > len)
+ replace(x, ind, paste(substr(x[ind], 1L, len - nchar(tail)), tail, sep = ""))
+}
diff --git a/R/coalesce.R b/R/coalesce.R
new file mode 100644
index 0000000..fdc1240
--- /dev/null
+++ b/R/coalesce.R
@@ -0,0 +1,33 @@
+#' Returns first non-missing, non-null argument.
+#'
+#' Returns first non-missing, non-null argument, otherwise
+#' \code{NULL}.
+#'
+#' @param ... [any]\cr
+#' Arguments.
+#' @return [any].
+#' @export
+#' @examples
+#' f = function(x,y) {
+#' print(coalesce(NULL, x, y))
+#' }
+#' f(y = 3)
+coalesce = function(...) {
+ dots = match.call(expand.dots = FALSE)$...
+ for (arg in dots) {
+ is_missing = if (is.symbol(arg)) {
+ eval(substitute(missing(symbol), list(symbol = arg)),
+ envir = parent.frame())
+ } else {
+ FALSE
+ }
+ if (!is_missing) {
+ value = tryCatch(eval(arg, envir = parent.frame()),
+ error = function(...) NULL)
+ if (!is.null(value)) {
+ return(value)
+ }
+ }
+ }
+ NULL
+}
diff --git a/R/collapse.R b/R/collapse.R
new file mode 100644
index 0000000..cb974b3
--- /dev/null
+++ b/R/collapse.R
@@ -0,0 +1,17 @@
+#' Collapse vector to string.
+#'
+#' A simple wrapper for \code{paste(x, collapse)}.
+#'
+#' @param x [\code{vector}]\cr
+#' Vector to collapse.
+#' @param sep [\code{character(1)}]\cr
+#' Passed to \code{collapse} in \code{\link{paste}}.
+#' Default is \dQuote{,}.
+#' @return [\code{character(1)}].
+#' @export
+#' @examples
+#' collapse(c("foo", "bar"))
+#' collapse(c("foo", "bar"), sep = ";")
+collapse = function(x, sep = ",") {
+ paste0(x, collapse = sep)
+}
diff --git a/R/collapsef.R b/R/collapsef.R
new file mode 100644
index 0000000..d0a5b66
--- /dev/null
+++ b/R/collapsef.R
@@ -0,0 +1,15 @@
+#' Collapse vector to string.
+#'
+#' A simple wrapper for \code{collapse(sprintf, ...)}.
+#'
+#' Useful for vectorized call to \code{\link{sprintf}}.
+#'
+#' @param ... [any]\cr
+#' See \code{\link{sprintf}}.
+#' @param sep [\code{character(1)}]\cr
+#' See \code{\link{collapse}}.
+#' @return [\code{character(1)}].
+#' @export
+collapsef = function(..., sep = ",") {
+ paste0(sprintf(...), collapse = sep)
+}
diff --git a/R/computeMode.R b/R/computeMode.R
new file mode 100644
index 0000000..078bdd2
--- /dev/null
+++ b/R/computeMode.R
@@ -0,0 +1,38 @@
+#' Compute statistical mode of a vector (value that occurs most frequently).
+#'
+#' Works for integer, numeric, factor and character vectors.
+#' The implementation is currently not extremely efficient.
+#'
+#' @param x [\code{vector}]\cr
+#' Factor, character, integer, numeric or logical vector.
+#' @param na.rm [\code{logical(1)}]\cr
+#' If \code{TRUE}, missing values in the data removed.
+#' if \code{FALSE}, they are used as a separate level and this level could therefore
+#' be returned as the most frequent one.
+#' Default is \code{TRUE}.
+#' @param ties.method [\code{character(1)}]\cr
+#' \dQuote{first}, \dQuote{random}, \dQuote{last}: Decide which value to take in case of ties.
+#' Default is \dQuote{random}.
+#' @return Modal value of length 1, data type depends on data type of \code{x}.
+#' @export
+#' @examples
+#' computeMode(c(1,2,3,3))
+computeMode = function(x, ties.method = "random", na.rm = TRUE) {
+ assertAtomicVector(x)
+ assertChoice(ties.method, c("first", "random", "last"))
+ assertFlag(na.rm)
+ #FIXME: no arg checks for speed currently
+ tab = table(x, useNA = ifelse(na.rm, "no", "ifany"))
+ y = max(tab)
+ mod = names(tab)[tab == y]
+ if (!is.factor(x))
+ mode(mod) = mode(x)
+ if (length(mod) > 1L)
+ switch(ties.method,
+ first = mod[1L],
+ random = sample(mod, 1L),
+ last = mod[length(mod)]
+ )
+ else
+ mod
+}
diff --git a/R/convertDataFrameCols.R b/R/convertDataFrameCols.R
new file mode 100644
index 0000000..930324c
--- /dev/null
+++ b/R/convertDataFrameCols.R
@@ -0,0 +1,52 @@
+#' Converts columns in a data frame to characters, factors or numerics.
+#'
+#' @param df [\code{data.frame}]\cr
+#' Data frame.
+#' @param chars.as.factor [\code{logical(1)}]\cr
+#' Should characters be converted to factors?
+#' Default is \code{FALSE}.
+#' @param factors.as.char [\code{logical(1)}]\cr
+#' Should characters be converted to factors?
+#' Default is \code{FALSE}.
+#' @param ints.as.num [\code{logical(1)}]\cr
+#' Should integers be converted to numerics?
+#' Default is \code{FALSE}.
+#' @param logicals.as.factor [\code{logical(1)}]\cr
+#' Should logicals be converted to factors?
+#' Default is \code{FALSE}.
+#' @export
+#' @return [\code{data.frame}].
+convertDataFrameCols = function(df, chars.as.factor = FALSE, factors.as.char = FALSE, ints.as.num = FALSE, logicals.as.factor = FALSE) {
+ assertDataFrame(df)
+ assertFlag(chars.as.factor)
+ assertFlag(factors.as.char)
+ assertFlag(ints.as.num)
+ assertFlag(logicals.as.factor)
+ df = x = as.list(df)
+
+ if (chars.as.factor) {
+ i = vlapply(df, is.character)
+ if (any(i))
+ x[i] = lapply(x[i], factor)
+ }
+
+ if (factors.as.char) {
+ i = vlapply(df, is.factor)
+ if (any(i))
+ x[i] = lapply(x[i], as.character)
+ }
+
+ if (ints.as.num) {
+ i = vlapply(df, is.integer)
+ if (any(i))
+ x[i] = lapply(x[i], as.double)
+ }
+
+ if (logicals.as.factor) {
+ i = vlapply(df, is.logical)
+ if (any(i))
+ x[i] = lapply(x[i], factor, levels = c("TRUE", "FALSE"))
+ }
+
+ as.data.frame(x, stringsAsFactors = FALSE)
+}
diff --git a/R/convertInteger.R b/R/convertInteger.R
new file mode 100644
index 0000000..00992d5
--- /dev/null
+++ b/R/convertInteger.R
@@ -0,0 +1,56 @@
+#' Conversion for single integer.
+#'
+#' Convert single numeric to integer only if the numeric represents a single integer,
+#' e.g. 1 to 1L.
+#' Otherwise the argument is returned unchanged.
+#'
+#' @param x [any]\cr
+#' Argument.
+#' @return Either a single integer if conversion was done or \code{x} unchanged.
+#' @export
+#' @examples
+#' str(convertInteger(1.0))
+#' str(convertInteger(1.3))
+#' str(convertInteger(c(1.0, 2.0)))
+#' str(convertInteger("foo"))
+convertInteger = function(x) {
+ if (is.integer(x) || length(x) != 1L)
+ return(x)
+ if (is.na(x))
+ return(as.integer(x))
+ if (is.numeric(x)) {
+ xi = as.integer(x)
+ if (isTRUE(all.equal(x, xi)))
+ return(xi)
+ }
+ return(x)
+}
+
+#' Conversion for integer vector.
+#'
+#' Convert numeric vector to integer vector if the numeric vector fully represents
+#' an integer vector,
+#' e.g. \code{c(1, 5)} to \code{c(1L, 5L)}.
+#' Otherwise the argument is returned unchanged.
+#'
+#' @param x [any]\cr
+#' Argument.
+#' @return Either an integer vector if conversion was done or \code{x} unchanged.
+#' @export
+#' @examples
+#' str(convertIntegers(1.0))
+#' str(convertIntegers(1.3))
+#' str(convertIntegers(c(1.0, 2.0)))
+#' str(convertIntegers("foo"))
+convertIntegers = function(x) {
+ if (is.integer(x))
+ return(x)
+ if (length(x) == 0L || (is.atomic(x) && all(is.na(x))))
+ return(as.integer(x))
+ if (is.numeric(x)) {
+ xi = as.integer(x)
+ if (isTRUE(all.equal(x, xi, check.names = FALSE)))
+ return(setNames(xi, names(x)))
+ }
+ return(x)
+}
diff --git a/R/convertListOfRowsToDataFrame.R b/R/convertListOfRowsToDataFrame.R
new file mode 100644
index 0000000..d9661b9
--- /dev/null
+++ b/R/convertListOfRowsToDataFrame.R
@@ -0,0 +1,54 @@
+#' Convert a list of row-vectors of equal structure to a data.frame.
+#'
+#' Elements are arranged in columns according to their name in each
+#' element of \code{rows}. Missing values are filled using NAs.
+#'
+#' @param rows [\code{list}]\cr
+#' List of rows. Each row is a list or vector of the same structure.
+#' That means all rows must have the same length and all corresponding elements must have the
+#' same class.
+#' @param strings.as.factors [\code{logical(1)}]\cr
+#' Convert character columns to factors?
+#' Default is \code{default.stringsAsFactors()}.
+#' @param row.names [\code{character} | \code{integer} | \code{NULL}]\cr
+#' Row names for result.
+#' By default the names of the list \code{rows} are taken.
+#' @param col.names [\code{character} | \code{integer}]\cr
+#' Column names for result.
+#' By default the names of an element of \code{rows} are taken.
+#' @return [\code{data.frame}].
+#' @export
+#' @examples
+#' convertListOfRowsToDataFrame(list(list(x = 1, y = "a"), list(x = 2, y = "b")))
+convertListOfRowsToDataFrame = function(rows, strings.as.factors = default.stringsAsFactors(),
+ row.names, col.names) {
+ assertList(rows)
+ assertList(rows, types = "vector")
+ if (!length(rows))
+ return(makeDataFrame(0L, 0L))
+ assertFlag(strings.as.factors)
+
+ if (missing(row.names))
+ row.names = names(rows)
+
+ # make names
+ rows = lapply(rows, function(x) setNames(x, make.names(names2(x, ""), unique = TRUE)))
+
+ cols = unique(unlist(lapply(rows, names2)))
+ if (anyMissing(cols))
+ stop("All row elements must be named")
+ if (!length(cols))
+ return(makeDataFrame(length(rows), 0L))
+
+ extract = function(cn) {
+ tmp = lapply(rows, function(x) if (is.list(x)) x[[cn]] else unname(x[cn]))
+ if (any(viapply(tmp, length) > 1L))
+ stop("Rows may only contain a single value per name")
+ simplify2array(replace(tmp, vlapply(tmp, is.null), NA))
+ }
+
+ d = data.frame(setNames(lapply(cols, extract), cols), row.names = row.names, stringsAsFactors = strings.as.factors)
+ if (!missing(col.names))
+ colnames(d) = col.names
+ return(d)
+}
diff --git a/R/convertMatrixType.R b/R/convertMatrixType.R
new file mode 100644
index 0000000..637273c
--- /dev/null
+++ b/R/convertMatrixType.R
@@ -0,0 +1,17 @@
+#' Converts storage type of a matrix.
+#'
+#' Works by setting \code{\link{mode}}.
+#'
+#' @param x [\code{matrix}]\cr.
+#' Matrix to convert.
+#' @param type [\code{character(1)}]\cr
+#' New storage type.
+#' @return [\code{matrix}].
+#' @note \code{as.mytype} drops dimension when used on a matrix.
+#' @export
+convertMatrixType = function(x, type) {
+ assertMatrix(x)
+ assertChoice(type, c("integer", "numeric", "complex", "character", "logical"))
+ storage.mode(x) = type
+ return(x)
+}
diff --git a/R/convertRowsToList.R b/R/convertRowsToList.R
new file mode 100644
index 0000000..f1fb8b8
--- /dev/null
+++ b/R/convertRowsToList.R
@@ -0,0 +1,65 @@
+#' Convert rows (columns) of data.frame or matrix to lists.
+#'
+#' For each row, one list/vector is constructed, each entry of
+#' the row becomes a list/vector element.
+#'
+#' @param x [\code{matrix} | \code{data.frame}]\cr
+#' Object to convert.
+#' @param name.list [\code{logical(1)}]\cr
+#' Name resulting list with names of rows (cols) of \code{x}?
+#' Default is \code{FALSE}.
+#' @param name.vector [\code{logical(1)}]\cr
+#' Name vector elements in resulting list with names of cols (rows) of \code{x}?
+#' Default is \code{FALSE}.
+#' @param factors.as.char [\code{logical(1)}]\cr
+#' If \code{x} is a data.frame, convert factor columns to
+#' string elements in the resulting lists?
+#' Default is \code{TRUE}.
+#' @param as.vector [\code{logical(1)}]\cr
+#' If \code{x} is a matrix, store rows as vectors in the resulting list - or otherwise as lists?
+#' Default is \code{TRUE}.
+#' @return [\code{list} of lists or vectors].
+#' @export
+convertRowsToList = function(x, name.list = TRUE, name.vector = FALSE,
+ factors.as.char = TRUE, as.vector = TRUE) {
+ assert(checkMatrix(x), checkDataFrame(x))
+ assertFlag(name.list)
+ assertFlag(name.vector)
+ assertFlag(factors.as.char)
+ assertFlag(as.vector)
+ ns.list = if (name.list) rownames(x) else NULL
+ ns.vector = if (name.vector) colnames(x) else NULL
+ if (is.matrix(x)) {
+ if (as.vector)
+ res = lapply(seq_row(x), function(i) setNames(x[i, ], ns.vector))
+ else
+ res = lapply(seq_row(x), function(i) setNames(as.list(x[i, ]), ns.vector))
+ } else if (is.data.frame(x)) {
+ if (factors.as.char)
+ x = convertDataFrameCols(x, factors.as.char = TRUE)
+ res = rowLapply(x, function(row) setNames(as.list(row), ns.vector))
+ }
+ setNames(res, ns.list)
+}
+
+#' @rdname convertRowsToList
+#' @export
+convertColsToList = function(x, name.list = FALSE, name.vector= FALSE,
+ factors.as.char = TRUE, as.vector = TRUE) {
+
+ # we need a special case for df and can ignore as.vector in it
+ if (is.data.frame(x)) {
+ if (factors.as.char)
+ x = convertDataFrameCols(x, factors.as.char = TRUE)
+ y = as.list(x)
+ if (name.vector) {
+ ns.vector = if (name.vector) colnames(x) else NULL
+ y = lapply(y, function(z) setNames(z, ns.vector))
+ }
+ colnames(y) = if (name.list) colnames(x) else NULL
+ return(y)
+ }
+
+ convertRowsToList(t(x), name.list = name.list, name.vector = name.vector,
+ factors.as.char = factors.as.char, as.vector = as.vector)
+}
diff --git a/R/convertToShortString.R b/R/convertToShortString.R
new file mode 100644
index 0000000..e3a713d
--- /dev/null
+++ b/R/convertToShortString.R
@@ -0,0 +1,60 @@
+#' @title Converts any R object to a descriptive string so it can be used in messages.
+#'
+#' @description
+#' Atomics: If of length 0 or 1, they are basically printed as they are.
+#' Numerics are formated with \code{num.format}.
+#' If of length greater than 1, they are collapsed witd \dQuote{,} and clipped.
+#' so they do not become excessively long.
+#'
+#' All others: Currently, only their class is simply printed
+#' like \dQuote{<data.frame>}.
+#'
+#' Lists: The mechanism above is applied (non-recursively) to their elements.
+#' The result looks like this:
+#' \dQuote{a = 1, <unamed> = 2, b = <data.frame>, c = <list>}.
+#'
+#' @param x [any]\cr
+#' The object.
+#' @param num.format [\code{character(1)}]\cr
+#' Used to format numerical scalars via \code{\link{sprintf}}.
+#' Default is \dQuote{\%.4g}.
+#' @param clip.len [\code{integer(1)}]\cr
+#' Used clip atomic vectors via \code{\link{clipString}}.
+#' Default is 15.
+#' @return [\code{character(1)}].
+#' @export
+#' @examples
+#' convertToShortString(list(a = 1, b = NULL, "foo", c = 1:10))
+convertToShortString = function(x, num.format = "%.4g", clip.len = 15L) {
+
+ # convert non-list object to string
+ convObj = function(x) {
+ if (is.null(x))
+ return("NULL")
+ if (is.atomic(x)) {
+ if (length(x) == 0L) {
+ sprintf("%s(0)", getClass1(x))
+ } else if (length(x) == 1L) {
+ if (is.double(x))
+ sprintf(num.format, x)
+ else
+ collapse(x)
+ } else {
+ clipString(collapse(sapply(x, convertToShortString), ","), clip.len)
+ }
+ } else {
+ paste("<", getClass1(x), ">", sep = "")
+ }
+ }
+
+ # handle only lists and not any derived data types
+ if (getClass1(x) == "list") {
+ if (length(x) == 0L)
+ return("")
+ ns = names2(x, missing.val = "<unnamed>")
+ ss = lapply(x, convObj)
+ collapse(paste(ns, "=", ss, sep = ""), ", ")
+ } else {
+ convObj(x)
+ }
+}
diff --git a/R/dapply.R b/R/dapply.R
new file mode 100644
index 0000000..70b9c58
--- /dev/null
+++ b/R/dapply.R
@@ -0,0 +1,45 @@
+#' Call \code{lapply} on an object and return a data.frame.
+#'
+#' Applies a function \code{fun} on each element of input \code{x}
+#' and combines the results as \code{data.frame} columns.
+#' The results will get replicated to have equal length
+#' if necessary and possible.
+#'
+#' @param x [\code{data.frame}]\cr
+#' Data frame.
+#' @param fun [\code{function}]\cr
+#' The function to apply.
+#' @param ... [any]\cr
+#' Further arguments passed down to \code{fun}.
+#' @param col.names [\code{character(1)}]\cr
+#' Column names for result.
+#' Default are the names of \code{x}.
+#' @export
+#' @return [\code{data.frame}].
+dapply = function(x, fun, ..., col.names) {
+ assertFunction(fun)
+
+ x = lapply(x, fun, ...)
+
+ if (missing(col.names)) {
+ ns = names2(x)
+ missing = which(is.na(ns))
+ if (length(missing))
+ names(x) = replace(ns, missing, paste0("Var.", missing))
+ } else {
+ assertCharacter(col.names, len = length(x), any.missing = FALSE)
+ names(x) = col.names
+ }
+
+ n = unique(viapply(x, length))
+ if (length(n) > 1L) {
+ max.n = max(n)
+ if (any(max.n %% n))
+ stop("Arguments imply differing number of rows: ", collapse(n, ", "))
+ x = lapply(x, rep_len, length.out = max.n)
+ n = max.n
+ }
+ attr(x, "row.names") = seq_len(n)
+ attr(x, "class") = "data.frame"
+ return(x)
+}
diff --git a/R/directory.R b/R/directory.R
new file mode 100644
index 0000000..43de72c
--- /dev/null
+++ b/R/directory.R
@@ -0,0 +1,35 @@
+#' Is one / are several files a directory?
+#'
+#' If a file does not exist, \code{FALSE} is returned.
+#'
+#' @param ... [\code{character(1)}]\cr
+#' File names, all strings.
+#' @return [\code{logical}].
+#' @export
+#' @examples
+#' print(isDirectory(tempdir()))
+#' print(isDirectory(tempfile()))
+isDirectory = function(...) {
+ paths = c(...)
+ if (.Platform$OS.type == "windows" && getRversion() < "3.0.2")
+ paths = sub("^([[:alpha:]]:)[/\\]*$", "\\1//", paths)
+ x = file.info(paths)$isdir
+ !is.na(x) & x
+}
+
+#' Is one / are several directories empty?
+#'
+#' If file does not exist or is not a directory, \code{FALSE} is returned.
+#'
+#' @param ... [\code{character(1)}]\cr
+#' Directory names, all strings.
+#' @return [\code{logical}].
+#' @export
+#' @examples
+#' print(isEmptyDirectory(tempdir()))
+#' print(isEmptyDirectory(tempfile()))
+isEmptyDirectory = function(...) {
+ vapply(list(...), FUN.VALUE = TRUE, FUN = function(x) {
+ isDirectory(x) && length(list.files(x, all.files = TRUE, include.dirs = TRUE)) == 2L
+ })
+}
diff --git a/R/do.call2.R b/R/do.call2.R
new file mode 100644
index 0000000..865f138
--- /dev/null
+++ b/R/do.call2.R
@@ -0,0 +1,27 @@
+#' Execute a function call similar to \code{do.call}.
+#'
+#' This function is supposed to be a replacement for \code{\link[base]{do.call}} in situations
+#' where you need to pass big R objects.
+#' Unlike \code{\link[base]{do.call}}, this function allows to pass objects via \code{...}
+#' to avoid a copy.
+#'
+#' @param fun [\code{character(1)}]\cr
+#' Name of the function to call.
+#' @param ... [any]\cr
+#' Arguments to \code{fun}. Best practice is to specify them in a \code{key = value} syntax.
+#' @param .args [\code{list}]\cr
+#' Arguments to \code{fun} as a (named) list. Will be passed after arguments in \code{...}.
+#' Default is \code{list()}.
+#' @return Return value of \code{fun}.
+#' @export
+#' @examples \dontrun{
+#' library(microbenchmark)
+#' x = 1:1e7
+#' microbenchmark(do.call(head, list(x, n = 1)), do.call2("head", x, n = 1))
+#' }
+do.call2 = function(fun, ..., .args = list()) {
+ assertString(fun)
+ ddd = match.call(expand.dots = FALSE)$...
+ expr = as.call(c(list(as.name(fun)), ddd, lapply(substitute(.args)[-1L], identity)))
+ eval.parent(expr, n = 1L)
+}
diff --git a/R/dropNamed.R b/R/dropNamed.R
new file mode 100644
index 0000000..850e70a
--- /dev/null
+++ b/R/dropNamed.R
@@ -0,0 +1,22 @@
+#' Drop named elements of an object.
+#'
+#' @param x [any]\cr
+#' Object to drop named elements from.
+#' For a matrix or a data frames this function drops named columns via
+#' the second argument of the binary index operator \code{[,]}.
+#' Otherwise, the unary index operator \code{[]} is used for dropping.
+#' @param drop [\code{character}]\cr
+#' Names of elements to drop.
+#' @return Subset of object of same type as \code{x}. The object is not simplified,
+#' i.e, no dimensions are dropped as \code{[,,drop = FALSE]} is used.
+#' @export
+dropNamed = function(x, drop = character(0L)) {
+ assertCharacter(drop, any.missing = FALSE)
+ if (length(drop) == 0L)
+ return(x)
+
+ if (is.matrix(x) || is.data.frame(x))
+ x[, setdiff(colnames(x), drop), drop = FALSE]
+ else
+ x[setdiff(names(x), drop)]
+}
diff --git a/R/ensureVector.R b/R/ensureVector.R
new file mode 100644
index 0000000..4228d35
--- /dev/null
+++ b/R/ensureVector.R
@@ -0,0 +1,43 @@
+#' Blow up single scalars / objects to vectors / list by replication.
+#'
+#' Useful for standard argument conversion where a user can input a single
+#' element, but this has to be replicated now n times for a resulting vector or list.
+#'
+#' @param x [any]\cr
+#' Input element.
+#' @param n [\code{integer}]\cr
+#' Desired length.
+#' @param cl [\code{character(1)}*]\cr
+#' Only do the operation if \code{x} inherits from this class, otherwise simply let x pass.
+#' Default is \code{NULL} which means to always do the operation.
+#' @param names [\code{character}*] \cr
+#' Names for result.
+#' Default is \code{NULL}, which means no names.
+#' @return Ether a vector or list of length \code{n} with replicated \code{x} or \code{x} unchanged..
+#' @export
+ensureVector = function(x, n, cl = NULL, names = NULL) {
+ n = convertInteger(n)
+ assertCount(n)
+
+ doit = isScalarValue(x) || !is.atomic(x)
+ if (!is.null(cl)) {
+ assertString(cl)
+ doit = doit && inherits(x, cl)
+ }
+
+ if (doit) {
+ if (isScalarValue(x))
+ xs = rep(x, n)
+ else
+ xs = replicate(n, x, simplify = FALSE)
+
+ if (!is.null(names)) {
+ assertCharacter(names, len = n, any.missing = FALSE)
+ names(xs) = names
+ }
+ return(xs)
+ } else {
+ return(x)
+ }
+}
+
diff --git a/R/explode.R b/R/explode.R
new file mode 100644
index 0000000..5540acb
--- /dev/null
+++ b/R/explode.R
@@ -0,0 +1,22 @@
+#' Split up a string into substrings.
+#'
+#' Split up a string into substrings according to a seperator.
+#'
+#' @param x [\code{character}]\cr
+#' Source string.
+#' @param sep [\code{character}]\cr
+#' Seperator whcih is used to split \code{x} into substrings.
+#' Default is \dQuote{ }.
+#' @return [\code{vector}]
+#' Vector of substrings.
+#' @export
+#' @examples
+#' explode("foo bar")
+#' explode("comma,seperated,values", sep = ",")
+explode = function(x, sep = " ") {
+ assertString(x)
+ assertString(sep)
+ #FIXME: why perl?
+ x.exploded = strsplit(x, sep, perl = TRUE)
+ return(x.exploded[[1L]])
+}
diff --git a/R/extractSubList.R b/R/extractSubList.R
new file mode 100644
index 0000000..71e20ce
--- /dev/null
+++ b/R/extractSubList.R
@@ -0,0 +1,72 @@
+#' Extracts a named element from a list of lists.
+#'
+#' @param xs [\code{list}]\cr
+#' A list of named lists.
+#' @param element [\code{character}]\cr
+#' Name of element(s) to extract from the list elements of \code{xs}.
+#' What happens is this: \code{x$el1$el2....}.
+#' @param element.value [any]\cr
+#' If given, \code{\link{vapply}} is used and this argument is passed to \code{FUN.VALUE}.
+#' Note that even for repeated indexing (if length(element) > 1) you only
+#' pass one value here which refers to the data type of the final result.
+#' @param simplify [\code{logical(1)} | character(1)]\cr
+#' If \code{FALSE} \code{\link{lapply}} is used, otherwise \code{\link{sapply}}.
+#' If \dQuote{cols}, we expect the elements to be vectors of the same length and they are
+#' arranged as the columns of the resulting matrix.
+#' If \dQuote{rows}, likewise, but rows of the resulting matrix.
+#' Default is \code{TRUE}.
+#' @param use.names [\code{logical(1)}]\cr
+#' If \code{TRUE} and \code{xs} is named, the result is named as \code{xs},
+#' otherwise the result is unnamed.
+#' Default is \code{TRUE}.
+#' @return [\code{list} | simplified \code{vector} | \code{matrix}]. See above.
+#' @export
+#' @examples
+#' xs = list(list(a = 1, b = 2), list(a = 5, b = 7))
+#' extractSubList(xs, "a")
+#' extractSubList(xs, "a", simplify = FALSE)
+extractSubList = function(xs, element, element.value, simplify = TRUE, use.names = TRUE) {
+ assertList(xs)
+ assert(checkFlag(simplify), checkChoice(simplify, c("cols", "rows")))
+ assertFlag(use.names)
+
+ # we save some time here if we only do the for loop in the complicated case
+ # the whole function is still not very nice due to the loop
+ # extractSubList should be C code anyway i guess....
+ doindex = if (length(element) == 1L) {
+ function(x) x[[element]]
+ } else {
+ function(x) {
+ for (el in element)
+ x = x[[el]]
+ return(x)
+ }
+ }
+
+ if (!missing(element.value)) {
+ ys = vapply(xs, doindex, FUN.VALUE = element.value)
+ } else if (isTRUE(simplify)) {
+ ys = sapply(xs, doindex, USE.NAMES = use.names)
+ } else {
+ ys = lapply(xs, doindex)
+ if (simplify == "rows")
+ ys = asMatrixRows(ys)
+ else if (simplify == "cols")
+ ys = asMatrixCols(ys)
+ }
+ ns = names(xs)
+ if (use.names && !is.null(ns)) {
+ if (isTRUE(simplify))
+ names(ys) = ns
+ else if (simplify == "rows")
+ rownames(ys) = ns
+ else if (simplify == "cols")
+ colnames(ys) = ns
+ } else {
+ if (simplify %in% c("rows", "rows"))
+ dimnames(ys) = NULL
+ else
+ names(ys) = NULL
+ }
+ return(ys)
+}
diff --git a/R/factor.R b/R/factor.R
new file mode 100644
index 0000000..ee06533
--- /dev/null
+++ b/R/factor.R
@@ -0,0 +1,24 @@
+#' Combine multiple factors and return a factor.
+#'
+#' Note that function does not inherit from \code{\link{c}} to not change R semantics behind your back when this
+#' package is loaded.
+#'
+#' @param ... [\code{factor}]\cr
+#' The factors.
+#' @return [\code{factor}].
+#' @export
+#' @examples
+#' f1 = factor(c("a", "b"))
+#' f2 = factor(c("b", "c"))
+#' print(c(f1, f2))
+#' print(cFactor(f1, f2))
+cFactor = function(...) {
+ args = lapply(list(...), as.factor)
+ newlevels = sort(unique(unlist(lapply(args, levels))))
+ ans = unlist(lapply(args, function(x) {
+ m = match(levels(x), newlevels)
+ m[as.integer(x)]
+ }))
+ levels(ans) = newlevels
+ setClasses(ans, "factor")
+}
diff --git a/R/filterNull.R b/R/filterNull.R
new file mode 100644
index 0000000..2531969
--- /dev/null
+++ b/R/filterNull.R
@@ -0,0 +1,10 @@
+#' Filter a list for NULL values
+#'
+#' @param li [\code{list}]\cr
+#' List.
+#' @return [\code{list}].
+#' @export
+filterNull = function(li) {
+ assertList(li)
+ li[!vlapply(li, is.null)]
+}
diff --git a/R/getAttributeNames.R b/R/getAttributeNames.R
new file mode 100644
index 0000000..089d518
--- /dev/null
+++ b/R/getAttributeNames.R
@@ -0,0 +1,11 @@
+#' Helper function for determining the vector of attribute names
+#' of a given object.
+#'
+#' @param obj [any]\cr
+#' Source object.
+#' @return [\code{character}]
+#' Vector of attribute names for the source object.
+#' @export
+getAttributeNames = function(obj) {
+ names(attributes(obj))
+}
diff --git a/R/getClass1.R b/R/getClass1.R
new file mode 100644
index 0000000..333b2bc
--- /dev/null
+++ b/R/getClass1.R
@@ -0,0 +1,10 @@
+#' Wrapper for \code{class(x)[1]}.
+#'
+#' @param x [any]\cr
+#' Input object.
+#' @return [\code{character(1)}].
+#' @note \code{getClass} is a function in \code{methods}. Do not confuse.
+#' @export
+getClass1 = function(x) {
+ class(x)[1L]
+}
diff --git a/R/getFirstLast.R b/R/getFirstLast.R
new file mode 100644
index 0000000..dcedbf2
--- /dev/null
+++ b/R/getFirstLast.R
@@ -0,0 +1,17 @@
+#' Get the first/last element of a list/vector.
+#'
+#' @param x [\code{list} | \code{vector}]\cr
+#' The list or vector.
+#' @return Selected element. The element name is dropped.
+#' @export
+getFirst = function(x) {
+ assertVector(x, min.len = 1L)
+ x[[1L]]
+}
+
+#' @rdname getFirst
+#' @export
+getLast = function(x) {
+ assertVector(x, min.len = 1L)
+ x[[length(x)]]
+}
diff --git a/R/getMaxColIndex.R b/R/getMaxColIndex.R
new file mode 100644
index 0000000..83d09a8
--- /dev/null
+++ b/R/getMaxColIndex.R
@@ -0,0 +1,55 @@
+#' Find row- or columnwise the index of the maximal / minimal element in a matrix.
+#'
+#' \code{getMaxIndexOfRows} returns the index of the maximal element of each row.
+#' \code{getMinIndexOfRows} returns the index of the minimal element of each row.
+#' \code{getMaxIndexOfCols} returns the index of the maximal element of each col.
+#' \code{getMinIndexOfCols} returns the index of the minimal element of each col.
+#' If a corresponding vector (row or col) is empty, possibly after NA removal, -1 is returned
+#' as index.
+#'
+#' @param x [\code{matrix(n,m)}] \cr
+#' Numerical input matrix.
+#' @param ties.method [\code{character(1)}]\cr
+#' How should ties be handled?
+#' Possible are: \dQuote{random}, \dQuote{first}, \dQuote{last}.
+#' Default is \dQuote{random}.
+#' @param na.rm [\code{logical(1)}]\cr
+#' If \code{FALSE}, NA is returned if an NA is encountered in \code{x}.
+#' If \code{TRUE}, NAs are disregarded.
+#' Default is \code{FALSE}
+#' @return [\code{integer(n)}].
+#' @export
+#' @useDynLib BBmisc c_getMaxIndexOfRows c_getMaxIndexOfCols
+#' @examples
+#' x = matrix(runif(5 * 3), ncol = 3)
+#' print(x)
+#' print(getMaxIndexOfRows(x))
+#' print(getMinIndexOfRows(x))
+getMaxIndexOfRows = function(x, ties.method = "random", na.rm = FALSE) {
+ mode(x) = "numeric"
+ ties.method = switch(ties.method, random = 1L, first = 2L, last = 3L,
+ stop("Unknown ties method"))
+ assertFlag(na.rm)
+ .Call(c_getMaxIndexOfRows, x, ties.method, na.rm)
+}
+
+#' @export
+#' @rdname getMaxIndexOfRows
+getMinIndexOfRows = function(x, ties.method = "random", na.rm = FALSE) {
+ getMaxIndexOfRows(-x, ties.method, na.rm)
+}
+
+#' @export
+#' @rdname getMaxIndexOfRows
+getMaxIndexOfCols = function(x, ties.method = "random", na.rm = FALSE) {
+ mode(x) = "numeric"
+ ties.method = switch(ties.method, random = 1L, first = 2L, last = 3L,
+ stop("Unknown ties method"))
+ .Call(c_getMaxIndexOfCols, x, ties.method, na.rm)
+}
+
+#' @export
+#' @rdname getMaxIndexOfRows
+getMinIndexOfCols = function(x, ties.method = "random", na.rm = FALSE) {
+ getMaxIndexOfCols(-x, ties.method, na.rm)
+}
diff --git a/R/getMaxIndex.R b/R/getMaxIndex.R
new file mode 100644
index 0000000..3aef7e9
--- /dev/null
+++ b/R/getMaxIndex.R
@@ -0,0 +1,31 @@
+#' Return index of maximal/minimal element in numerical vector.
+#'
+#' If \code{x} is empty or only contains NAs which are to be removed,
+#' -1 is returned.
+#'
+#' @param x [\code{numeric}]\cr
+#' Input vector.
+#' @param ties.method [\code{character(1)}]\cr
+#' How should ties be handled?
+#' Possible are: \dQuote{random}, \dQuote{first}, \dQuote{last}.
+#' Default is \dQuote{random}.
+#' @param na.rm [\code{logical(1)}]\cr
+#' If \code{FALSE}, NA is returned if an NA is encountered in \code{x}.
+#' If \code{TRUE}, NAs are disregarded.
+#' Default is \code{FALSE}
+#' @return [\code{integer(1)}].
+#' @export
+#' @useDynLib BBmisc c_getMaxIndex
+getMaxIndex = function(x, ties.method = "random", na.rm = FALSE) {
+ ties.method = switch(ties.method, random = 1L, first = 2L, last = 3L,
+ stop("Unknown ties method"))
+ assertFlag(na.rm)
+ .Call(c_getMaxIndex, as.numeric(x), ties.method, na.rm)
+}
+
+
+#' @export
+#' @rdname getMaxIndex
+getMinIndex = function(x, ties.method = "random", na.rm = FALSE) {
+ getMaxIndex(-as.numeric(x), ties.method, na.rm)
+}
diff --git a/R/getOperatingSystem.R b/R/getOperatingSystem.R
new file mode 100644
index 0000000..b43e268
--- /dev/null
+++ b/R/getOperatingSystem.R
@@ -0,0 +1,39 @@
+#' Functions to determine the operating system.
+#'
+#' \itemize{
+#' \item{getOperatingSystem}{Simple wrapper for \code{.Platform$OS.type}, returns \code{character(1)}.}
+#' \item{isUnix}{Predicate for OS string, returns \code{logical(1)}. Currently this would include Unix, Linux and Mac flavours.}
+#' \item{isLinux}{Predicate for sysname string, returns \code{logical(1)}.}
+#' \item{isDarwin}{Predicate for sysname string, returns \code{logical(1)}.}
+#' \item{isWindows}{Predicate for OS string, returns \code{logical(1)}.}
+#' }
+#'
+#' @return See above.
+#' @export
+getOperatingSystem = function() {
+ .Platform$OS.type
+}
+
+#' @rdname getOperatingSystem
+#' @export
+isWindows = function() {
+ .Platform$OS.type == "windows"
+}
+
+#' @rdname getOperatingSystem
+#' @export
+isUnix = function() {
+ .Platform$OS.type == "unix"
+}
+
+#' @rdname getOperatingSystem
+#' @export
+isLinux = function() {
+ isUnix() && grepl("linux", Sys.info()["sysname"], ignore.case = TRUE)
+}
+
+#' @rdname getOperatingSystem
+#' @export
+isDarwin = function() {
+ isUnix() && grepl("darwin", Sys.info()["sysname"], ignore.case = TRUE)
+}
diff --git a/R/getRelativePath.R b/R/getRelativePath.R
new file mode 100644
index 0000000..18a7d7d
--- /dev/null
+++ b/R/getRelativePath.R
@@ -0,0 +1,43 @@
+#' Construct a path relative to another
+#'
+#' Constructs a relative path from path \code{from} to path \code{to}.
+#' If this is not possible (i.e. different drive letters on windows systems),
+#' \code{NA} is returned.
+#'
+#' @param to [\code{character(1)}]\cr
+#' Where the relative path should point to.
+#' @param from [\code{character(1)}]\cr
+#' From which part to start.
+#' Default is \code{\link[base]{getwd}}.
+#' @param ignore.case [\code{logical(1)}]\cr
+#' Should path comparisons be made case insensitve?
+#' Default is \code{TRUE} on Windows systems and \code{FALSE} on other systems.
+#' @return [character(1)]: A relative path.
+#' @export
+getRelativePath = function(to, from = getwd(), ignore.case = isWindows()) {
+ numberCommonParts = function(p1, p2) {
+ for (i in seq_len(min(length(p1), length(p2)))) {
+ if (p1[i] != p2[i])
+ return(i - 1L)
+ }
+ return(if (is.null(i)) 0L else i)
+ }
+
+ from = splitPath(from)
+ to = splitPath(to)
+ assertFlag(ignore.case)
+ if (length(from$drive) != length(to$drive))
+ return(NA_character_)
+ if (length(from$drive) > 0L && length(to$drive) > 0L && from$drive != to$drive)
+ return(NA_character_)
+
+ if (ignore.case)
+ i = numberCommonParts(tolower(from$path), tolower(to$path))
+ else
+ i = numberCommonParts(from$path, to$path)
+
+ res = c(rep.int("..", length(from$path) - i), tail(to$path, ifelse(i == 0L, Inf, -i)))
+ if (length(res) == 0L)
+ res = "."
+ collapse(res, .Platform$file.sep)
+}
diff --git a/R/getUnixTime.R b/R/getUnixTime.R
new file mode 100644
index 0000000..ec0f00b
--- /dev/null
+++ b/R/getUnixTime.R
@@ -0,0 +1,9 @@
+#' Current time in seconds.
+#'
+#' Simple wrapper for \code{as.integer(Sys.time())}.
+#'
+#' @return [\code{integer(1)}].
+#' @export
+getUnixTime = function() {
+ as.integer(Sys.time())
+}
diff --git a/R/getUsedFactorLevels.R b/R/getUsedFactorLevels.R
new file mode 100644
index 0000000..adf57aa
--- /dev/null
+++ b/R/getUsedFactorLevels.R
@@ -0,0 +1,12 @@
+#' Determines used factor levels.
+#'
+#' Determines the factor levels of a factor type vector
+#' that are actually occuring in it.
+#'
+#' @param x [\code{factor}]\cr
+#' The factor.
+#' @return [\code{character}]
+#' @export
+getUsedFactorLevels = function(x) {
+ intersect(levels(x), unique(x))
+}
diff --git a/R/hasAttributes.R b/R/hasAttributes.R
new file mode 100644
index 0000000..bc9fc47
--- /dev/null
+++ b/R/hasAttributes.R
@@ -0,0 +1,13 @@
+#' Check if given object has certain attributes.
+#'
+#' @param obj [mixed]\cr
+#' Arbitrary R object.
+#' @param attribute.names [\code{character}]\cr
+#' Vector of strings, i.e., attribute names.
+#' @return [\code{logical(1)}]
+#' \code{TRUE} if object \code{x} contains all attributes from \code{attributeNames}
+#' and \code{FALSE} otherwise.
+#' @export
+hasAttributes = function(obj, attribute.names) {
+ isSubset(attribute.names, getAttributeNames(obj))
+}
diff --git a/R/insert.R b/R/insert.R
new file mode 100644
index 0000000..7ca9faa
--- /dev/null
+++ b/R/insert.R
@@ -0,0 +1,30 @@
+#' Insert elements from one list/vector into another list/vector.
+#'
+#' Inserts elements from \code{xs2} into \code{xs1} by name,
+#' overwriting elements of equal names.
+#'
+#' @param xs1 [\code{list}]\cr
+#' First list/vector.
+#' @param xs2 [\code{list}]\cr
+#' Second vector/list. Must be fully and uniquely named.
+#' @param elements [\code{character}]\cr
+#' Elements from \code{xs2} to insert into \code{xs1}.
+#' Default is all.
+#' @return \code{x1} with replaced elements from \code{x2}.
+#' @export
+#' @examples
+#' xs1 = list(a = 1, b = 2)
+#' xs2 = list(b = 1, c = 4)
+#' insert(xs1, xs2)
+#' insert(xs1, xs2, elements = "c")
+insert = function(xs1, xs2, elements) {
+ if (length(xs2) > 0L) {
+ if (missing(elements)) {
+ xs1[names(xs2)] = xs2
+ } else {
+ elements = intersect(elements, names(xs2))
+ xs1[elements] = xs2[elements]
+ }
+ }
+ return(xs1)
+}
diff --git a/R/isExpensiveExampleOk.R b/R/isExpensiveExampleOk.R
new file mode 100644
index 0000000..0e9a797
--- /dev/null
+++ b/R/isExpensiveExampleOk.R
@@ -0,0 +1,20 @@
+#' Conditional checking for expensive examples.
+#'
+#' Queries environment variable \dQuote{R_EXPENSIVE_EXAMPLE_OK}.
+#' Returns \code{TRUE} iff set exactly to \dQuote{TRUE}.
+#' This allows conditional checking of expensive examples in packages
+#' via R CMD CHECK, so they are not run on CRAN, but at least
+#' on your local computer.
+#' A better option than \dQuote{dont_run} in many cases, where such examples
+#' are not checked at all.
+#'
+#' @return [\code{logical(1)}].
+#' @export
+#' @examples
+#' # extremely costly random number generation, that we dont want checked on CRAN
+#' if (isExpensiveExampleOk()) {
+#' runif(1)
+#' }
+isExpensiveExampleOk = function() {
+ Sys.getenv("R_EXPENSIVE_EXAMPLE_OK") == "TRUE"
+}
diff --git a/R/isFALSE.R b/R/isFALSE.R
new file mode 100644
index 0000000..63f2659
--- /dev/null
+++ b/R/isFALSE.R
@@ -0,0 +1,12 @@
+#' A wrapper for \code{identical(x, FALSE)}.
+#'
+#' @param x [any]\cr
+#' Your object.
+#' @return [\code{logical(1)}].
+#' @export
+#' @examples
+#' isFALSE(0)
+#' isFALSE(FALSE)
+isFALSE = function(x) {
+ identical(x, FALSE)
+}
diff --git a/R/isProperlyNamed.R b/R/isProperlyNamed.R
new file mode 100644
index 0000000..5c466cd
--- /dev/null
+++ b/R/isProperlyNamed.R
@@ -0,0 +1,16 @@
+#' Are all elements of a list / vector uniquely named?
+#'
+#' \code{NA} or \dQuote{} are not allowed as names.
+#'
+#' @param x [\code{vector}]\cr
+#' The vector or list.
+#' @return [\code{logical(1)}].
+#' @export
+#' @examples
+#' isProperlyNamed(list(1))
+#' isProperlyNamed(list(a = 1))
+#' isProperlyNamed(list(a = 1, 2))
+isProperlyNamed = function(x) {
+ ns = names2(x)
+ length(x) == 0L || !(any(is.na(ns)) || anyDuplicated(ns))
+}
diff --git a/R/isScalarNA.R b/R/isScalarNA.R
new file mode 100644
index 0000000..19bcc2f
--- /dev/null
+++ b/R/isScalarNA.R
@@ -0,0 +1,10 @@
+#' Checks whether an object is a scalar NA value.
+#'
+#' Checks whether object is from \code{(NA, NA_integer, NA_real_, NA_character_, NA_complex_)}.
+#' @param x [any]\cr
+#' Object to check.
+#' @return [\code{logical(1)}].
+#' @export
+isScalarNA = function(x) {
+ is.atomic(x) && length(x) == 1L && is.na(x)
+}
diff --git a/R/isScalarValue.R b/R/isScalarValue.R
new file mode 100644
index 0000000..afe98af
--- /dev/null
+++ b/R/isScalarValue.R
@@ -0,0 +1,70 @@
+#' Is given argument an atomic vector or factor of length 1?
+#'
+#' More specific functions for scalars of a given type exist, too.
+#'
+#' @param x [any]\cr
+#' Argument.
+#' @param na.ok [\code{logical(1)}]\cr
+#' Is \code{NA} considered a scalar?
+#' Default is \code{TRUE}.
+#' @param null.ok [\code{logical(1)}]\cr
+#' Is \code{NULL} considered a scalar?
+#' Default is \code{FALSE}.
+#' @param type [\code{character(1)}]\cr
+#' Allows to restrict to specific type, e.g., \dQuote{numeric}?
+#' But instead of this argument you might want to consider using \code{isScalar<Type>}.
+#' Default is \dQuote{atomic}, so no special restriction.
+#' @return [\code{logical(1)}].
+#' @export
+isScalarValue = function(x, na.ok = TRUE, null.ok = FALSE, type = "atomic") {
+ if (is.null(x))
+ return(null.ok)
+ # not really cool switch, but maybe fastest option
+ istype = switch(type,
+ "atomic" = is.atomic,
+ "logical" = is.logical,
+ "numeric" = is.numeric,
+ "integer" = is.integer,
+ "complex" = is.complex,
+ "chararacter" = is.character,
+ "factor" = is.factor
+ )
+ istype(x) && length(x) == 1L && (na.ok || !is.na(x))
+}
+
+#' @rdname isScalarValue
+#' @export
+isScalarLogical = function(x, na.ok = TRUE, null.ok = FALSE) {
+ isScalarValue(x, na.ok, null.ok, "logical")
+}
+
+#' @rdname isScalarValue
+#' @export
+isScalarNumeric = function(x, na.ok = TRUE, null.ok = FALSE) {
+ isScalarValue(x, na.ok, null.ok, "numeric")
+}
+
+#' @rdname isScalarValue
+#' @export
+isScalarInteger = function(x, na.ok = TRUE, null.ok = FALSE) {
+ isScalarValue(x, na.ok, null.ok, "integer")
+}
+
+#' @rdname isScalarValue
+#' @export
+isScalarComplex = function(x, na.ok = TRUE, null.ok = FALSE) {
+ isScalarValue(x, na.ok, null.ok, "complex")
+}
+
+#' @rdname isScalarValue
+#' @export
+isScalarCharacter = function(x, na.ok = TRUE, null.ok = FALSE) {
+ isScalarValue(x, na.ok, null.ok, "chararacter")
+}
+
+#' @rdname isScalarValue
+#' @export
+isScalarFactor = function(x, na.ok = TRUE, null.ok = FALSE) {
+ isScalarValue(x, na.ok, null.ok, "factor")
+}
+
diff --git a/R/isSubset.R b/R/isSubset.R
new file mode 100644
index 0000000..209208f
--- /dev/null
+++ b/R/isSubset.R
@@ -0,0 +1,21 @@
+#' Check subset relation on two vectors.
+#'
+#' @param x [\code{vector}]\cr
+#' Source vector.
+#' @param y [\code{vector}]\cr
+#' Vector of the same mode as \code{x}.
+#' @param strict [\code{logical(1)}]\cr
+#' Checks for strict/proper subset relation.
+#' @return [\code{logical(1)}]
+#' \code{TRUE} if each element of \code{x} is also contained in \code{y}, i. e.,
+#' if \code{x} is a subset of \code{y} and \code{FALSE} otherwise.
+#' @export
+isSubset = function(x, y, strict = FALSE) {
+ assertFlag(strict)
+ if (length(x) == 0L)
+ return(TRUE)
+ res = all(x %in% y)
+ if (strict)
+ res = res & !isSubset(y, x)
+ return(res)
+}
diff --git a/R/isSuperset.R b/R/isSuperset.R
new file mode 100644
index 0000000..797c051
--- /dev/null
+++ b/R/isSuperset.R
@@ -0,0 +1,15 @@
+#' Check superset relation on two vectors.
+#'
+#' @param x [\code{vector}]\cr
+#' Source vector.
+#' @param y [\code{vector}]\cr
+#' Vector of the same mode as \code{x}.
+#' @param strict [\code{logical(1)}]\cr
+#' Checks for strict/proper superset relation.
+#' @return [\code{logical(1)}]
+#' \code{TRUE} if each element of \code{y} is also contained in \code{x}, i. e.,
+#' if \code{y} is a subset of \code{x} and \code{FALSE} otherwise.
+#' @export
+isSuperset = function(x, y, strict = FALSE) {
+ isSubset(y, x, strict)
+}
diff --git a/R/isValidName.R b/R/isValidName.R
new file mode 100644
index 0000000..5dc8695
--- /dev/null
+++ b/R/isValidName.R
@@ -0,0 +1,18 @@
+#' Can some strings be used for column or list element names without problems?
+#'
+#' @param x [\code{character}]\cr
+#' Character vector to check.
+#' @param unique [\code{logical(1)}]\cr
+#' Should the names be unique?
+#' Default is \code{TRUE}.
+#' @return [\code{logical}]. One Boolean entry for each string in \code{x}.
+#' If the entries are not unique and \code{unique} is enabled, the first duplicate will
+#' be \code{FALSE}.
+#' @export
+isValidName = function(x, unique = TRUE) {
+ if (!is.character(x))
+ x = as.character(x)
+ # check that make.names does not change the string (otherwise it would be invalid),
+ # names are unique (for e.g. colnames) and stuff like ..1 is disallowed
+ x == make.names(x, isTRUE(unique)) & !grepl("^\\.\\.[0-9]$", x)
+}
diff --git a/R/is_error.R b/R/is_error.R
new file mode 100644
index 0000000..3ac9809
--- /dev/null
+++ b/R/is_error.R
@@ -0,0 +1,19 @@
+#' Is return value of try an exception?
+#'
+#' Checks if an object is of class \dQuote{try-error} or
+#' \dQuote{error}.
+#'
+#' @param x [any]\cr
+#' Any object, usually the return value of \code{\link[base]{try}},
+#' \code{\link[base]{tryCatch}}, or a function which may return a
+#' \code{\link[base]{simpleError}}.
+#' @return [\code{logical(1)}].
+#' @export
+#' @examples
+#' x = try(stop("foo"))
+#' print(is.error(x))
+#' x = 1
+#' print(is.error(x))
+is.error = function(x) {
+ inherits(x, c("try-error", "error"))
+}
diff --git a/R/itostr.R b/R/itostr.R
new file mode 100644
index 0000000..9a94e0d
--- /dev/null
+++ b/R/itostr.R
@@ -0,0 +1,23 @@
+#' Convert Integers to Strings
+#'
+#' This is the counterpart of \code{\link[base]{strtoi}}.
+#' For a base greater than \sQuote{10}, letters \sQuote{a} to \sQuote{z}
+#' are used to represent \sQuote{10} to \sQuote{35}.
+#'
+#' @param x [\code{integer}]\cr
+#' Vector of integers to convert.
+#' @param base [\code{integer(1)}]\cr
+#' Base for conversion. Values between 2 and 36 (inclusive) are allowed.
+#' @return \code{character(length(x))}.
+#' @export
+#' @examples
+#' # binary representation of the first 10 natural numbers
+#' itostr(1:10, 2)
+#'
+#' # base36 encoding of a large number
+#' itostr(1e7, 36)
+itostr = function(x, base = 10L) {
+ x = asInteger(x, any.missing = FALSE, lower = 0L)
+ base = asInt(base, na.ok = FALSE, lower = 2L, upper = 36L)
+ .Call("itostr", x, base, PACKAGE = "BBmisc")
+}
diff --git a/R/lib.R b/R/lib.R
new file mode 100644
index 0000000..acbe978
--- /dev/null
+++ b/R/lib.R
@@ -0,0 +1,27 @@
+#' A wrapper for \code{library}.
+#'
+#' Tries to load packages. If the packages are not found, they will be installed from
+#' the default repository. This function is intended for use in interactive sessions
+#' and should not be used by other packages.
+#'
+#' @param ... [any]\cr
+#' Package names.
+#' @return [\code{logical}]: Named logical vector determining the success
+#' of package load.
+#' @export
+#' @examples \dontrun{
+#' lib("BBmisc", "MASS", "rpart")
+#' }
+lib = function(...) {
+ getLib = function(pkg) {
+ ok = suppressWarnings(require(pkg, character.only = TRUE))
+ if (!ok && !is.error(try(install.packages(pkg)))) {
+ ok = require(pkg, character.only = TRUE)
+ }
+ ok
+ }
+
+ pkgs = unique(c(...))
+ assertCharacter(pkgs, any.missing = FALSE)
+ vlapply(pkgs, getLib)
+}
diff --git a/R/load2.R b/R/load2.R
new file mode 100644
index 0000000..f762a2c
--- /dev/null
+++ b/R/load2.R
@@ -0,0 +1,50 @@
+#' Load RData file and return objects in it.
+#'
+#' @param file [\code{character(1)}]\cr
+#' File to load.
+#' @param parts [\code{character}]\cr
+#' Elements in file to load.
+#' Default is all.
+#' @param simplify [\code{logical(1)}]\cr
+#' If \code{TRUE}, a list is only returned if \code{parts} and the file contain both more
+#' than 1 element, otherwise the element is directly returned.
+#' Default is \code{TRUE}.
+#' @param envir [\code{environment(1)}]\cr
+#' Assign objects to this environment.
+#' Default is not to assign.
+#' @param impute [\code{ANY}]\cr
+#' If \code{file} does not exists, return \code{impute} instead.
+#' Default is missing which will result in an exception if \code{file} is not found.
+#' @return Either a single object or a list.
+#' @export
+#' @examples
+#' fn = tempfile()
+#' save2(file = fn, a = 1, b = 2, c = 3)
+#' load2(fn, parts = "a")
+#' load2(fn, parts = c("a", "c"))
+load2 = function(file, parts, simplify = TRUE, envir, impute) {
+ assertFlag(simplify)
+ ee = new.env()
+ if (!missing(impute) && !file.exists(file))
+ return(impute)
+ load(file, envir = ee)
+ ns = ls(ee, all.names = TRUE)
+ if (!missing(parts)) {
+ assertCharacter(parts, any.missing = FALSE)
+ d = setdiff(parts, ns)
+ if (length(d) > 0L)
+ stopf("File %s does not contain: %s", file, collapse(d))
+ } else {
+ parts = ns
+ }
+ if (!missing(envir)) {
+ lapply(ns, function(x) assign(x, ee[[x]], envir = envir))
+ }
+ if (simplify) {
+ if (length(ns) == 1L)
+ return(ee[[ns]])
+ if (length(parts) == 1L)
+ return(ee[[parts]])
+ }
+ mget(parts, envir = ee)
+}
diff --git a/R/lsort.R b/R/lsort.R
new file mode 100644
index 0000000..6371ecd
--- /dev/null
+++ b/R/lsort.R
@@ -0,0 +1,14 @@
+#' A wrapper for \code{\link{sort}} to sort using the \dQuote{C} collating rules.
+#'
+#' @param ...
+#' Options passed to sort.
+#' @return See \code{\link{sort}}.
+#' @export
+lsort = function(...) {
+ cur = Sys.getlocale("LC_COLLATE")
+ if (cur != "C") {
+ Sys.setlocale("LC_COLLATE", "C")
+ on.exit(Sys.setlocale("LC_COLLATE", cur))
+ }
+ sort(...)
+}
diff --git a/R/makeDataFrame.R b/R/makeDataFrame.R
new file mode 100644
index 0000000..0030e04
--- /dev/null
+++ b/R/makeDataFrame.R
@@ -0,0 +1,60 @@
+#' Initialize data.frame in a convenient way.
+#'
+#' @param nrow [\code{integer(1)}]\cr
+#' Nubmer of rows.
+#' @param ncol [\code{integer(1)}]\cr
+#' Number of columns.
+#' @param col.types [\code{character(ncol)} | \code{character(1)}]\cr
+#' Data types of columns.
+#' If you only pass one type, it will be replicated.
+#' Supported are all atomic modes also supported by
+#' \code{\link[base]{vector}}, i.e. all common data frame types except factors.
+#' @param init [any]\cr
+#' Scalar object to initialize all elements of the data.frame.
+#' You do not need to specify \code{col.types} if you pass this.
+#' @param row.names [\code{character} | \code{integer} | \code{NULL}]\cr
+#' Row names.
+#' Default is \code{NULL}.
+#' @param col.names [\code{character} | \code{integer}]\cr
+#' Column names.
+#' Default is \dQuote{V1}, \dQuote{V2}, and so on.
+#' @export
+#' @examples
+#' print(makeDataFrame(3, 2, init = 7))
+#' print(makeDataFrame(3, 2, "logical"))
+#' print(makeDataFrame(3, 2, c("logical", "numeric")))
+makeDataFrame = function(nrow, ncol, col.types, init, row.names = NULL, col.names = sprintf("V%i", seq_len(ncol))) {
+ nrow = asCount(nrow)
+ ncol = asCount(ncol)
+ if (!missing(col.types))
+ assertCharacter(col.types, min.len = 1L, any.missing = FALSE)
+ if (!missing(init)) {
+ if(!isScalarValue(init))
+ stop("'init' must be a scalar value!")
+ if (!missing(col.types)) {
+ if (length(col.types) > 1L)
+ stop("If 'init' is given, length of col.types must be 1!")
+ if (identical(class(init)[1L], "col.types"))
+ stop("Class of 'init' must match given column type!")
+ }
+ }
+ if (!missing(col.types) && length(col.types) == 1L)
+ col.types = rep.int(col.types, ncol)
+ if (!is.null(row.names))
+ assert(checkIntegerish(row.names, len = nrow), checkCharacter(row.names, len = nrow))
+
+ assert(checkIntegerish(col.names, len = ncol), checkCharacter(col.names, len = ncol))
+
+ if (nrow == 0L && ncol == 0L)
+ df = data.frame()
+ else if (ncol == 0L)
+ df = data.frame(matrix(nrow = nrow, ncol = 0))
+ else if (missing(init))
+ df = lapply(col.types, vector, length = nrow)
+ else
+ df = replicate(ncol, rep.int(init, nrow), simplify = FALSE)
+ df = as.data.frame(df, stringsAsFactors = FALSE)
+ rownames(df) = row.names
+ colnames(df) = col.names
+ return(df)
+}
diff --git a/R/makeProgressBar.R b/R/makeProgressBar.R
new file mode 100644
index 0000000..362705e
--- /dev/null
+++ b/R/makeProgressBar.R
@@ -0,0 +1,166 @@
+#' @title Create a progress bar with estimated time.
+#'
+#' @description
+#' Create a progress bar function that displays the estimated time till
+#' completion and optional messages. Call the returned functions \code{set} or
+#' \code{inc} during a loop to change the display.
+#' Note that you are not allowed to decrease the value of the bar.
+#' If you call these function without setting any of the arguments
+#' the bar is simply redrawn with the current value.
+#' For errorhandling use \code{error} and have a look at the example below.
+#'
+#' You can globally change the behavior of all bars by setting the option
+#' \code{options(BBmisc.ProgressBar.style)} either to \dQuote{text} (the default)
+#' or \dQuote{off}, which display no bars at all.
+#'
+#' You can globally change the width of all bars by setting the option
+#' \code{options(BBmisc.ProgressBar.width)}. By default this is \code{getOption("width")}.
+#'
+#' You can globally set the stream where the output of the bar is directed by setting the option
+#' \code{options(BBmisc.ProgressBar.stream)} either to \dQuote{stderr} (the default)
+#' or \dQuote{stdout}. Note that using the latter will result in the bar being shown in
+#' reports generated by Sweave or knitr, what you probably do not want.
+#'
+#' @param min [\code{numeric(1)}]\cr
+#' Minimum value, default is 0.
+#' @param max [\code{numeric(1)}]\cr
+#' Maximum value, default is 100.
+#' @param label [\code{character(1)}]\cr
+#' Label shown in front of the progress bar.
+#' Note that if you later set \code{msg} in the progress bar function,
+#' the message will be left-padded to the length of this label, therefore
+#' it should be at least as long as the longest message you want to display.
+#' Default is \dQuote{}.
+#' @param char [\code{character(1)}]\cr
+#' A single character used to display progress in the bar.
+#' Default is \sQuote{+}.
+#' @param style [\code{character(1)}]\cr
+#' Style of the progress bar. Default is set via options (see details).
+#' @param width [\code{integer(1)}]\cr
+#' Width of the progress bar. Default is set via options (see details).
+#' @param stream [\code{character(1)}]\cr
+#' Stream to use. Default is set via options (see details).
+#' @return [\code{\link{ProgressBar}}]. A list with following functions:
+#' \item{set [\code{function(value, msg = label)}]}{Set the bar to a value and possibly display a message instead of the label.}
+#' \item{inc [\code{function(value, msg = label)}]}{Increase the bar and possibly display a message instead of the label.}
+#' \item{kill [\code{function(clear = FALSE)}]}{Kill the bar so it cannot be used anymore. Cursor is moved to new line. You can also erase its display.}
+#' \item{error [\code{function(e)}]}{Useful in \code{tryCatch} to properly display error messages below the bar. See the example.}
+#' @export
+#' @aliases ProgressBar
+#' @examples
+#' bar = makeProgressBar(max = 5, label = "test-bar")
+#' for (i in 0:5) {
+#' bar$set(i)
+#' Sys.sleep(0.2)
+#' }
+#' bar = makeProgressBar(max = 5, label = "test-bar")
+#' for (i in 1:5) {
+#' bar$inc(1)
+#' Sys.sleep(0.2)
+#' }
+#' # display errors properly (in next line)
+#' \dontrun{
+#' f = function(i) if (i>2) stop("foo")
+#' bar = makeProgressBar(max = 5, label = "test-bar")
+#' for (i in 1:5) {
+#' tryCatch ({
+#' f(i)
+#' bar$set(i)
+#' }, error = bar$error)
+#' }
+#' }
+makeProgressBar = function(min = 0, max = 100, label = "", char = "+",
+ style = getOption("BBmisc.ProgressBar.style", "text"),
+ width = getOption("BBmisc.ProgressBar.width", getOption("width")),
+ stream = getOption("BBmisc.ProgressBar.stream", "stderr")) {
+ assertNumber(min)
+ assertNumber(max)
+ assertString(label)
+ assertChoice(style, c("text", "off"))
+ assertInt(width, lower = 30L)
+ assertChoice(stream, c("stderr", "stdout"))
+
+ if (style == "off")
+ return(structure(list(
+ set = function(value, msg = label) invisible(NULL),
+ inc = function(inc, msg = label) invisible(NULL),
+ kill = function(clear = FALSE) invisible(NULL),
+ error = function(e) stop(e)
+ ), class = "ProgressBar"))
+
+ mycat = if (stream == "stdout")
+ function(...) cat(...)
+ else
+ function(...) cat(..., file = stderr())
+
+ ## label |................................| xxx% (hh:mm:ss)
+ label.width = nchar(label)
+ bar.width = width - label.width - 21L
+ bar = rep(" ", bar.width)
+
+ start.time = as.integer(Sys.time())
+ delta = max - min
+ kill.line = "\r"
+ killed = FALSE
+ cur.value = min
+ draw = function(value, inc, msg) {
+ if (!missing(value) && !missing(inc))
+ stop("You must not set value and inc!")
+ else if (!missing(value))
+ assertNumber(value, lower = max(min, cur.value), upper = max)
+ else if (!missing(inc)) {
+ assertNumber(inc, lower = 0, upper = max - cur.value)
+ value = cur.value + inc
+ } else {
+ value = cur.value
+ }
+ if (!killed) {
+ # special case for min == max, weird "empty" bar, but might happen...
+ if (value == max)
+ rate = 1
+ else
+ rate = (value - min) / delta
+ bin = round(rate * bar.width)
+ bar[seq(bin)] <<- char
+ delta.time = as.integer(Sys.time()) - start.time
+ if (value == min)
+ rest.time = 0
+ else
+ rest.time = (max - value) * (delta.time / (value - min))
+ rest.time = splitTime(rest.time, "hours")
+ # as a precaution, so we can _always_ print in the progress bar cat
+ if (rest.time["hours"] > 99)
+ rest.time[] = 99
+ mycat(kill.line)
+ msg = sprintf(sprintf("%%%is", label.width), msg)
+ mycat(sprintf("%s |%s| %3i%% (%02i:%02i:%02i)", msg, collapse(bar, sep = ""), round(rate*100),
+ rest.time["hours"], rest.time["minutes"], rest.time["seconds"]))
+ if (value == max)
+ kill()
+ flush.console()
+ }
+ cur.value <<- value
+ }
+ clear = function(newline = TRUE) {
+ mycat(kill.line)
+ mycat(rep(" ", width))
+ if (newline)
+ mycat("\n")
+ }
+ kill = function(clear = FALSE) {
+ if (clear)
+ clear(newline = TRUE)
+ else
+ mycat("\n")
+ killed <<- TRUE
+ }
+ makeS3Obj("ProgressBar",
+ set = function(value, msg = label) draw(value = value, msg = msg),
+ inc = function(inc, msg = label) draw(inc = inc, msg = msg),
+ kill = kill,
+ error = function(e) {
+ kill(clear = FALSE)
+ stop(e)
+ }
+ )
+}
diff --git a/R/makeS3Obj.R b/R/makeS3Obj.R
new file mode 100644
index 0000000..48d2b15
--- /dev/null
+++ b/R/makeS3Obj.R
@@ -0,0 +1,16 @@
+#' Simple constructor for S3 objects based on lists.
+#'
+#' Simple wrapper for \code{as.list} and \code{\link{setClasses}}.
+#'
+#' @param classes [\code{character}]\cr
+#' Class(es) for constructed object.
+#' @param ... [any]\cr
+#' Key-value pairs for class members.
+#' @return Object.
+#' @export
+#' @examples
+#' makeS3Obj("car", speed = 100, color = "red")
+makeS3Obj = function(classes, ...) {
+ assertCharacter(classes, min.len = 1L, any.missing = FALSE)
+ setClasses(list(...), classes = classes)
+}
diff --git a/R/makeSimpleFileLogger.R b/R/makeSimpleFileLogger.R
new file mode 100644
index 0000000..711f5a5
--- /dev/null
+++ b/R/makeSimpleFileLogger.R
@@ -0,0 +1,85 @@
+#' Simple logger which outputs to a file.
+#'
+#' Creates a simple file logger closure to log to a file, including time stamps.
+#' An optional buffer holds the last few log messages.
+#'
+#' @param logfile [\code{character(1)}]\cr
+#' File to log to.
+#' @param touch [\code{logical(1)}]\cr
+#' Should the file be created before the first log message?
+#' Default is \code{FALSE}.
+#' @param keep [\code{integer(1)}]\cr
+#' Number of log messages to keep in memory for quick access.
+#' Default is \code{10}.
+#' @return [\code{\link{SimpleFileLogger}}]. A list with following functions:
+#' \item{log [\code{function(msg)}]}{Send log message.}
+#' \item{getMessages [\code{function(n)}]}{Get last \code{n} log messages.}
+#' \item{clear [\code{function()}]}{Resets logger and deletes log file.}
+#' \item{getSize [\code{function()}]}{Returns the number of logs written.}
+#' \item{getLogfile [\code{function()}]}{Returns the full file name logs are written to.}
+#' @export
+#' @aliases SimpleFileLogger
+makeSimpleFileLogger = function(logfile, touch = FALSE, keep = 10L) {
+ assertString(logfile)
+ assertFlag(touch)
+ keep = asCount(keep)
+ assertDirectoryExists(dirname(logfile), "w")
+ if (touch && !file.create(logfile))
+ stopf("Could not create file '%s'", logfile)
+ if (keep)
+ buffer = circularBuffer("character", keep)
+ n.lines = 0L
+
+ makeS3Obj("SimpleFileLogger",
+ log = function(msg) {
+ if (keep)
+ buffer$push(msg)
+ if (!touch && n.lines == 0L && !file.create(logfile))
+ stopf("Could not create file '%s'", logfile)
+ catf("<%s> %s", as.character(Sys.time()), msg, file = logfile, append = TRUE, newline = TRUE)
+ n.lines <<- n.lines + 1L
+ },
+ getMessages = function(n) {
+ if (!keep || n > keep)
+ return(sub("^<.+> (.*)", "\\1", tail(readLines(logfile), n)))
+ buffer$get(n)
+ },
+ clear = function() {
+ if (keep)
+ buffer$clear()
+ n.lines <<- 0L
+ file.remove(logfile)
+ },
+ getSize = function() {
+ n.lines
+ },
+ getLogfile = function() {
+ logfile
+ }
+ )
+}
+
+circularBuffer = function(type, capacity) {
+ st = vector(type, capacity)
+ stored = 0L
+ pos = 0L
+
+ list(
+ push = function(x) {
+ pos <<- pos %% capacity + 1L
+ stored <<- min(capacity, stored + 1L)
+ st[[pos]] <<- x
+ },
+ get = function(n = 1L) {
+ head(st[rev((seq_len(stored) + pos - 1L) %% stored + 1L)], n)
+ },
+ stored = function() {
+ stored
+ },
+ clear = function() {
+ st <<- vector(type, capacity)
+ stored <<- 0
+ pos <<- 0
+ }
+ )
+}
diff --git a/R/mapValues.R b/R/mapValues.R
new file mode 100644
index 0000000..35b588f
--- /dev/null
+++ b/R/mapValues.R
@@ -0,0 +1,55 @@
+#' Replace values in atomic vectors
+#'
+#' @details
+#' Replaces values specified in \code{from} with values in \code{to}.
+#' Regular expression matching can be enabled which calls \code{\link[base]{gsub}} iteratively
+#' on \code{x} to replace all patterns in \code{from} with replacements in \code{to}.
+#'
+#' @param x [\code{atomic}]\cr
+#' Atomic vector. If \code{x} is a factor, all replacements work on the levels.
+#' @param from [\code{atomic}]\cr
+#' Atomic vector with values to replace, same length as \code{to}.
+#' @param to [\code{atomic}]\cr
+#' Atomic vector with replacements, same length as \code{from}.
+#' @param regex [\code{logical}]\cr
+#' Use regular expression matching? Default is \code{FALSE}.
+#' @param ignore.case [\code{logical}]\cr
+#' Argument passed to \code{\link[base]{gsub}}.
+#' @param perl [\code{logical}]\cr
+#' Argument passed to \code{\link[base]{gsub}}.
+#' @param fixed [\code{logical}]\cr
+#' Argument passed to \code{\link[base]{gsub}}.
+#' @return [\code{atomic}].
+#' @export
+#' @examples
+#' # replace integers
+#' x = 1:5
+#' mapValues(x, c(2, 3), c(99, 100))
+#'
+#' # replace factor levels using regex matching
+#' x = factor(c("aab", "aba", "baa"))
+#' mapValues(x, "a.a", "zzz", regex = TRUE)
+mapValues = function(x, from, to, regex = FALSE, ignore.case = FALSE, perl = FALSE, fixed = FALSE) {
+ assertAtomic(x)
+ assertAtomic(from)
+ assertAtomic(to, len = length(from))
+ assertFlag(regex)
+
+ map = function(x, from, to) {
+ if (regex) {
+ for (i in seq_along(from))
+ x = gsub(from[i], to[i], x, ignore.case = ignore.case, perl = perl, fixed = fixed)
+ } else {
+ m = match(x, from, nomatch = NA_integer_)
+ found = !is.na(m)
+ x[found] = to[m[found]]
+ }
+ return(x)
+ }
+
+ if (is.factor(x)) {
+ levels(x) = map(levels(x), from, to)
+ return(x)
+ }
+ return(map(x, from, to))
+}
diff --git a/R/matchDataFrameSubset.R b/R/matchDataFrameSubset.R
new file mode 100644
index 0000000..96378ee
--- /dev/null
+++ b/R/matchDataFrameSubset.R
@@ -0,0 +1,25 @@
+# FIXME: not used anywhere?
+matchDataFrameSubset = function(df, ss, factors.as.chars = TRUE) {
+ checkArg(df, c("list", "data.frame"))
+ checkArg(ss, c("list", "data.frame"))
+ if (!isProperlyNamed(df))
+ stop("'df' is not proberbly named")
+ if (!isProperlyNamed(ss))
+ stop("'ss' is not proberbly named")
+ if (any(names(ss) %nin% names(df)))
+ stop("Names of 'ss' not found in 'df'")
+ if (is.list(df))
+ df = as.data.frame(df, stringsAsFactors = FALSE)
+ if (is.list(ss))
+ ss = as.data.frame(ss, stringsAsFactors = FALSE)
+
+ df = subset(df, select = names(ss))
+
+ if (factors.as.chars) {
+ df = convertDataFrameCols(df, factors.as.char = TRUE)
+ ss = convertDataFrameCols(ss, factors.as.char = TRUE)
+ }
+
+ conv = function(x) rawToChar(serialize(x, connection = NULL, ascii = TRUE))
+ match(rowSapply(ss, conv, use.names = FALSE), rowSapply(df, conv, use.names = FALSE))
+}
diff --git a/R/messagef.R b/R/messagef.R
new file mode 100644
index 0000000..1ddfab6
--- /dev/null
+++ b/R/messagef.R
@@ -0,0 +1,16 @@
+#' Wrapper for message and sprintf.
+#'
+#' A simple wrapper for \code{message(sprintf(...))}.
+#'
+#' @param ... [any]\cr
+#' See \code{\link{sprintf}}.
+#' @param .newline [logical(1)]\cr
+#' Add a newline to the message. Default is \code{TRUE}.
+#' @return Nothing.
+#' @export
+#' @examples
+#' msg = "a message"
+#' warningf("this is %s", msg)
+messagef = function(..., .newline = TRUE) {
+ message(sprintf(...), appendLF = .newline)
+}
diff --git a/R/namedList.R b/R/namedList.R
new file mode 100644
index 0000000..049d24e
--- /dev/null
+++ b/R/namedList.R
@@ -0,0 +1,22 @@
+#' Create named list, possibly initialized with a certain element.
+#'
+#' @param names [\code{character}]\cr
+#' Names of elements.
+#' @param init [valid R expression]\cr
+#' If given all list elements are initialized to this, otherwise
+#' \code{NULL} is used.
+#' @return [\code{list}].
+#' @export
+#' @examples
+#' namedList(c("a", "b"))
+#' namedList(c("a", "b"), init = 1)
+namedList = function(names, init) {
+ if (missing(names))
+ return(list())
+ n = length(names)
+ if (missing(init))
+ xs = vector("list", n)
+ else
+ xs = replicate(n, init, simplify = FALSE)
+ setNames(xs, names)
+}
diff --git a/R/names2.R b/R/names2.R
new file mode 100644
index 0000000..91e9c97
--- /dev/null
+++ b/R/names2.R
@@ -0,0 +1,26 @@
+#' Replacement for names which always returns a vector.
+#'
+#' A simple wrapper for \code{\link[base]{names}}.
+#' Returns a vector even if no names attribute is set.
+#' Values \code{NA} and \code{""} are treated as missing and
+#' replaced with the value provided in \code{missing.val}.
+#'
+#' @param x [\code{ANY}]\cr
+#' Object, probably named.
+#' @param missing.val [\code{ANY}]\cr
+#' Value to set for missing names. Default is \code{NA_character_}.
+#' @return [\code{character}]: vector of the same length as \code{x}.
+#' @export
+#' @examples
+#' x = 1:3
+#' names(x)
+#' names2(x)
+#' names(x[1:2]) = letters[1:2]
+#' names(x)
+#' names2(x)
+names2 = function(x, missing.val = NA_character_) {
+ n = names(x)
+ if (is.null(n))
+ return(rep.int(missing.val, length(x)))
+ replace(n, is.na(n) | n == "", missing.val)
+}
diff --git a/R/nin.R b/R/nin.R
new file mode 100644
index 0000000..52f2651
--- /dev/null
+++ b/R/nin.R
@@ -0,0 +1,12 @@
+#' Simply a negated \code{in} operator.
+#'
+#' @param x [\code{vector}]\cr
+#' Values that should not be in \code{y}.
+#' @param y [\code{vector}]\cr
+#' Values to match against.
+#' @usage x \%nin\% y
+#' @rdname nin
+#' @export
+`%nin%` = function(x, y) {
+ !match(x, y, nomatch = 0L)
+}
diff --git a/R/normalize.R b/R/normalize.R
new file mode 100644
index 0000000..9a3d11b
--- /dev/null
+++ b/R/normalize.R
@@ -0,0 +1,97 @@
+#' @title Normalizes numeric data to a given scale.
+#'
+#' @description
+#' Currently implemented for numeric vectors, numeric matrices and data.frame.
+#' For matrixes one can operate on rows or columns
+#' For data.frames, only the numeric columns are touched, all others are left unchanged.
+#' For constant vectors / rows / columns most methods fail, special behaviour for this
+#' case is implemented.
+#'
+#' The method also handles NAs in in \code{x} and leaves them untouched.
+#'
+#' @param x [\code{numeric} | \code{matrix} | \code{data.frame}]\cr
+#' Input vector.
+#' @param method [\code{character(1)}]\cr
+#' Normalizing method. Available are:\cr
+#' \dQuote{center}: Subtract mean.\cr
+#' \dQuote{scale}: Divide by standard deviation.\cr
+#' \dQuote{standardize}: Center and scale.\cr
+#' \dQuote{range}: Scale to a given range.\cr
+#' @param range [\code{numeric(2)}]\cr
+#' Range for method \dQuote{range}.
+#' The first value represents the replacement for the min value, the second is the substitute for the max value.
+#' So it is possible to reverse the order by giving \code{range = c(1,0)}.
+#' Default is \code{c(0,1)}.
+#' @param margin [\code{integer(1)}]\cr
+#' 1 = rows, 2 = cols.
+#' Same is in \code{\link{apply}}
+#' Default is 1.
+#' @param on.constant [\code{character(1)}]\cr
+#' How should constant vectors be treated? Only used, of \dQuote{method != center},
+#' since this methods does not fail for constant vectors. Possible actions are:\cr
+#' \dQuote{quiet}: Depending on the method, treat them quietly:\cr
+#' \dQuote{scale}: No division by standard deviation is done, input values.
+#' will be returned untouched.\cr
+#' \dQuote{standardize}: Only the mean is subtracted, no division is done.\cr
+#' \dQuote{range}: All values are mapped to the mean of the given range.\cr
+#' \dQuote{warn}: Same behaviour as \dQuote{quiet}, but print a warning message.\cr
+#' \dQuote{stop}: Stop with an error.\cr
+#' @return [\code{numeric} | \code{matrix} | \code{data.frame}].
+#' @seealso \code{\link{scale}}
+#' @export
+normalize = function(x, method = "standardize", range = c(0, 1), margin = 1L, on.constant = "quiet") {
+ assertChoice(method, c("range", "standardize", "center", "scale"))
+ assertNumeric(range, len = 2L, any.missing = FALSE)
+ assertChoice(on.constant, c("quiet", "warn", "stop"))
+ UseMethod("normalize")
+}
+
+#' @export
+normalize.numeric = function(x, method = "standardize", range = c(0, 1), margin = 1L, on.constant = "quiet") {
+ y = normalize2(x, method, range, on.constant = on.constant)
+ # scale call below returns matrices
+ if (is.matrix(y))
+ y = y[,1L]
+ return(y)
+}
+
+#' @export
+normalize.matrix = function(x, method = "standardize", range = c(0, 1), margin = 1L, on.constant = "quiet") {
+ x = apply(x, margin, normalize2, method = method, range = range, on.constant = on.constant)
+ if (margin == 1L)
+ x = t(x)
+ return(x)
+}
+
+#' @export
+normalize.data.frame = function(x, method = "standardize", range = c(0, 1), margin = 1L, on.constant = "quiet") {
+ isnum = sapply(x, is.numeric)
+ if (any(isnum))
+ x[, isnum] = as.data.frame(lapply(x[, isnum, drop = FALSE], normalize2, method = method,
+ range = range, on.constant = on.constant))
+ return(x)
+}
+
+normalize2 = function(x, method, range, on.constant) {
+ # is x a constant vector?
+ if (length(unique(x[!is.na(x)])) == 1L) {
+ switch(on.constant,
+ warn = warning("Constant vector in normalization."),
+ stop = stop("Constant vector in normalization."))
+ switch(method,
+ center = scale(x, center = TRUE, scale = FALSE),
+ range = ifelse(is.na(x), NA, mean(range)),
+ standardize = scale(x, center = TRUE, scale = FALSE),
+ scale = x
+ )
+ } else {
+ switch(method,
+ range = (x - min(x, na.rm = TRUE)) / diff(range(x, na.rm = TRUE)) * diff(range) + range[1L],
+ standardize = scale(x, center = TRUE, scale = TRUE),
+ center = scale(x, center = TRUE, scale = FALSE),
+ scale = scale(x, center = FALSE, scale = sd(x, na.rm = TRUE))
+ )
+ }
+}
+
+
diff --git a/R/optimizeSubInts.R b/R/optimizeSubInts.R
new file mode 100644
index 0000000..6a30c79
--- /dev/null
+++ b/R/optimizeSubInts.R
@@ -0,0 +1,41 @@
+#' @title Naive multi-start version of \code{\link{optimize}} for global optimization.
+#'
+#' @description
+#' The univariate \code{\link{optimize}} can stop at arbitrarily bad points when
+#' \code{f} is not unimodal. This functions mitigates this effect in a very naive way:
+#' \code{interval} is subdivided into \code{nsub} equally sized subintervals,
+#' \code{\link{optimize}} is run on all of them (and on the original big interval) and
+#' the best obtained point is returned.
+#'
+#' @param f See \code{\link{optimize}}.
+#' @param interval See \code{\link{optimize}}.
+#' @param ... See \code{\link{optimize}}.
+#' @param lower See \code{\link{optimize}}.
+#' @param upper See \code{\link{optimize}}.
+#' @param maximum See \code{\link{optimize}}.
+#' @param tol See \code{\link{optimize}}.
+#' @param nsub [\code{integer(1)}]\cr
+#' Number of subintervals. A value of 1 implies normal \code{\link{optimize}} behavior.
+#' Default is 50L.
+#' @return See \code{\link{optimize}}.
+#' @export
+optimizeSubInts = function(f, interval, ..., lower = min(interval), upper = max(interval),
+ maximum = FALSE, tol = .Machine$double.eps^0.25, nsub = 50L) {
+ nsub = asCount(nsub, positive = TRUE)
+
+ interval = c(lower, upper)
+ # run on normal interval
+ best = optimize(f = f, interval = interval, maximum = maximum, tol = tol)
+
+ # run on smaller partitions
+ if (nsub > 1L) {
+ mult = ifelse(maximum, -1, 1)
+ grid = seq(lower, upper, length.out = nsub - 1L)
+ for (j in seq_len(length(grid)-1L)) {
+ res = optimize(f = f, interval = c(grid[j], grid[j+1L]), maximum = maximum, tol = tol)
+ if (mult * res$objective < mult * best$objective)
+ best = res
+ }
+ }
+ return(best)
+}
diff --git a/R/pause.R b/R/pause.R
new file mode 100644
index 0000000..1cabff0
--- /dev/null
+++ b/R/pause.R
@@ -0,0 +1,6 @@
+#' Pause in interactive mode and continue on <Enter>.
+#' @export
+pause = function() {
+ if (interactive())
+ readline("Pause. Press <Enter> to continue.")
+}
diff --git a/R/printStrToChar.R b/R/printStrToChar.R
new file mode 100644
index 0000000..9074c1e
--- /dev/null
+++ b/R/printStrToChar.R
@@ -0,0 +1,17 @@
+#' Print \code{str(x)} of an object to a string / character vector.
+#'
+#' @param x [any]\cr
+#' Object to print
+#' @param collapse [\code{character(1)}]\cr
+#' Used to collapse multiple lines.
+#' \code{NULL} means no collapsing, vector is returned.
+#' Default is \dQuote{\\n}.
+#' @return [\code{character}].
+#' @export
+#' @examples
+#' printStrToChar(iris)
+printStrToChar = function(x, collapse = "\n") {
+ d = printToChar(str(x), collapse = NULL)
+ # remove NULL from str
+ collapse(d[-length(d)], collapse)
+}
diff --git a/R/printToChar.R b/R/printToChar.R
new file mode 100644
index 0000000..248d7b5
--- /dev/null
+++ b/R/printToChar.R
@@ -0,0 +1,27 @@
+#' Prints object to a string / character vector.
+#'
+#' @param x [any]\cr
+#' Object to print
+#' @param collapse [\code{character(1)}]\cr
+#' Used to collapse multiple lines.
+#' \code{NULL} means no collapsing, vector is returned.
+#' Default is \dQuote{\\n}.
+#' @return [\code{character}].
+#' @export
+#' @examples
+#' x = data.frame(a = 1:2, b = 3:4)
+#' str(printToChar(x))
+printToChar = function(x, collapse = "\n") {
+ rval = NULL
+ con = textConnection("rval", "w", local = TRUE)
+ sink(con)
+ on.exit({
+ sink()
+ close(con)
+ })
+ print(x)
+ if (!is.null(collapse))
+ paste(rval, collapse = collapse)
+ else
+ rval
+}
diff --git a/R/rangeVal.R b/R/rangeVal.R
new file mode 100644
index 0000000..16fd73e
--- /dev/null
+++ b/R/rangeVal.R
@@ -0,0 +1,19 @@
+#' Calculate range statistic.
+#'
+#' A simple wrapper for \code{diff(range(x))}, so \code{max(x) - min(x)}.
+#'
+#' @param x [\code{numeric}]\cr
+#' The vector.
+#' @param na.rm [\code{logical(1)}]\cr
+#' If \code{FALSE}, NA is returned if an NA is encountered in \code{x}.
+#' If \code{TRUE}, NAs are disregarded.
+#' Default is \code{FALSE}
+#' @return [\code{numeric(1)}].
+#' @export
+rangeVal = function(x, na.rm = FALSE) {
+ assertNumeric(x, min.len = 1L, any.missing = TRUE)
+ assertFlag(na.rm)
+ if (allMissing(x))
+ return(NA_real_)
+ diff(range(x, na.rm = na.rm))
+}
diff --git a/R/requirePackages.R b/R/requirePackages.R
new file mode 100644
index 0000000..10642ce
--- /dev/null
+++ b/R/requirePackages.R
@@ -0,0 +1,99 @@
+#' @title Require some packages.
+#'
+#' @description
+#' Packages are loaded either via \code{\link{requireNamespace}} or \code{\link{require}}.
+#'
+#' If some packages could not be loaded and \code{stop} is \code{TRUE}
+#' the following exception is thrown:
+#' \dQuote{For <why> please install the following packages: <missing packages>}.
+#' If \code{why} is \code{NULL} the message is:
+#' \dQuote{Please install the following packages: <missing packages>}.
+#'
+#' @param packs [\code{character}]\cr
+#' Names of packages.
+#' If a package name is prefixed with \dQuote{!}, it will be attached using \code{\link[base]{require}}.
+#' If a package name is prefixed with \dQuote{_}, its namespace will be loaded using \code{\link[base]{requireNamespace}}.
+#' If there is no prefix, argument \code{default.method} determines how to deal with package loading.
+#' @param min.versions [\code{character}]\cr
+#' A char vector specifying required minimal version numbers for a subset of packages in \code{packs}.
+#' Must be named and all names must be in \code{packs}.
+#' The only exception is when \code{packs} is only a single string, then you are allowed to pass
+#' an unnamed version string here.
+#' Default is \code{NULL}, meaning no special version requirements
+#' @param why [\code{character(1)}]\cr
+#' Short string explaining why packages are required.
+#' Default is an empty string.
+#' @param stop [\code{logical(1)}]\cr
+#' Should an exception be thrown for missing packages?
+#' Default is \code{TRUE}.
+#' @param suppress.warnings [\code{logical(1)}]\cr
+#' Should warnings be supressed while requiring?
+#' Default is \code{FALSE}.
+#' @param default.method [\code{character(1)}]\cr
+#' If the packages are not explicitly prefixed with \dQuote{!} or \dQuote{_},
+#' this arguments determines the default. Possible values are \dQuote{attach} and
+#' \dQuote{load}.
+#' Note that the default is \dQuote{attach}, but this might/will change in a future version, so
+#' please make sure to always explicitly set this.
+#' @return [\code{logical}]. Named logical vector describing which packages could be loaded (with required version).
+#' Same length as \code{packs}.
+#' @export
+#' @examples
+#' requirePackages(c("BBmisc", "base"), why = "BBmisc example")
+requirePackages = function(packs, min.versions = NULL, why = "", stop = TRUE, suppress.warnings = FALSE, default.method = "attach") {
+ assertCharacter(packs, any.missing = FALSE)
+ if (!is.null(min.versions)) {
+ assertCharacter(min.versions)
+ if (length(packs) == 1L && length(min.versions) == 1L && is.null(names(min.versions)))
+ names(min.versions) = packs
+ else
+ assertSubset(names(min.versions), packs)
+ }
+ assertFlag(stop)
+ assertFlag(suppress.warnings)
+ assertChoice(default.method, choices = c("load", "attach"))
+
+ char = substr(packs, 1L, 1L)
+ force.attach = (char == "!")
+ force.load = (char == "_")
+ ns.only = if (default.method == "load") !force.attach else force.load
+ packs = substr(packs, 1L + (force.load | force.attach), nchar(packs))
+ suppressor = if (suppress.warnings) suppressWarnings else identity
+
+ packs.ok = unlist(Map(function(pack, ns.only) {
+ if (ns.only) {
+ suppressor(requireNamespace(pack, quietly = TRUE))
+ } else {
+ suppressor(require(pack, character.only = TRUE))
+ }
+ }, pack = packs, ns.only = ns.only))
+
+ if (stop && !all(packs.ok)) {
+ ps = collapse(packs[!packs.ok])
+ if (nzchar(why))
+ stopf("For %s please install the following packages: %s", why, ps)
+ else
+ stopf("Please install the following packages: %s", ps)
+ }
+
+ if (!is.null(min.versions)) {
+ packs.wrong.version = character(0L)
+ for (j in seq_along(min.versions)) {
+ pn = names(min.versions)[j]
+ mv = min.versions[j]
+ if (packageVersion(pn) < mv) {
+ packs.ok[pn] = FALSE
+ packs.wrong.version = c(packs.wrong.version, sprintf("%s >= %s", pn, mv))
+ }
+ }
+ if (stop && length(packs.wrong.version) > 0L) {
+ ps = collapse(packs.wrong.version)
+ if (nzchar(why))
+ stopf("For %s the package version requirements are not fulfilled: %s", why, ps)
+ else
+ stopf("The package version requirements are not fulfilled: %s", ps)
+ }
+ }
+
+ return(packs.ok)
+}
diff --git a/R/rowLapply.R b/R/rowLapply.R
new file mode 100644
index 0000000..26175a0
--- /dev/null
+++ b/R/rowLapply.R
@@ -0,0 +1,77 @@
+#' Apply function to rows of a data frame.
+#'
+#' Just like an \code{\link[base]{lapply}} on data frames,
+#' but on the rows.
+#'
+#' @param df [\code{data.frame}]\cr
+#' Data frame.
+#' @param fun [\code{function}]\cr
+#' Function to apply. Rows are passed as list or vector,
+#' depending on argument \code{unlist}, as first argument.
+#' @param ... [\code{ANY}]\cr
+#' Additional arguments for \code{fun}.
+#' @param unlist [\code{logical(1)}]\cr
+#' Unlist the row? Note that automatic conversion may be triggered for
+#' lists of mixed data types
+#' Default is \code{FALSE}.
+#' @param simplify [\code{logical(1)} | character(1)]\cr
+#' Should the result be simplified?
+#' See \code{\link{sapply}}.
+#' If \dQuote{cols}, we expect the call results to be vectors of the same length and they are
+#' arranged as the columns of the resulting matrix.
+#' If \dQuote{rows}, likewise, but rows of the resulting matrix.
+#' Default is \code{TRUE}.
+#' @param use.names [\code{logical(1)}]\cr
+#' Should result be named by the row names of \code{df}?
+#' Default is \code{TRUE}.
+#' @return [\code{list} or simplified object]. Length is \code{nrow(df)}.
+#' @export
+#' @examples
+#' rowLapply(iris, function(x) x$Sepal.Length + x$Sepal.Width)
+rowLapply = function(df, fun, ..., unlist = FALSE) {
+ assertDataFrame(df)
+ fun = match.fun(fun)
+ assertFlag(unlist)
+ if (unlist) {
+ .wrap = function(.i, .df, .fun, ...)
+ .fun(unlist(.df[.i, , drop = FALSE], recursive = FALSE, use.names = TRUE), ...)
+ } else {
+ .wrap = function(.i, .df, .fun, ...)
+ .fun(as.list(.df[.i, , drop = FALSE]), ...)
+ }
+
+ lapply(seq_row(df), .wrap, .fun = fun, .df = df, ...)
+}
+
+#' @export
+#' @rdname rowLapply
+rowSapply = function(df, fun, ..., unlist = FALSE, simplify = TRUE, use.names = TRUE) {
+ assert(checkFlag(simplify), checkChoice(simplify, c("cols", "rows")))
+ assertFlag(use.names)
+ ys = rowLapply(df, fun, ..., unlist = unlist)
+
+ # simplify result
+ if (length(ys) > 0L) {
+ if (isTRUE(simplify)) {
+ ys = simplify2array(ys)
+ } else if (simplify == "rows") {
+ ys = asMatrixRows(ys)
+ } else if (simplify == "cols") {
+ ys = asMatrixCols(ys)
+ }
+ }
+
+ # set names
+ if (use.names) {
+ if (is.matrix(ys)) {
+ colnames(ys) = rownames(df)
+ rownames(ys) = NULL
+ } else {
+ names(ys) = rownames(df)
+ }
+ } else {
+ names(ys) = NULL
+ }
+
+ return(ys)
+}
diff --git a/R/save2.R b/R/save2.R
new file mode 100644
index 0000000..ba03c83
--- /dev/null
+++ b/R/save2.R
@@ -0,0 +1,34 @@
+#' Save multiple objects to a file.
+#'
+#' A simple wrapper for \code{\link[base]{save}}. Understands key = value syntax to save
+#' objects using arbitrary variable names. All options of \code{\link[base]{save}},
+#' except \code{list} and \code{envir}, are available and passed to
+#' \code{\link[base]{save}}.
+#'
+#' @param file
+#' File to save.
+#' @param ... [\code{any}]\cr
+#' Will be converted to an environment and then passed to \code{\link[base]{save}}.
+#' @param ascii
+#' See help of \code{\link[base]{save}}.
+#' @param version
+#' See help of \code{\link[base]{save}}.
+#' @param compress
+#' See help of \code{\link[base]{save}}.
+#' @param compression_level
+#' See help of \code{\link[base]{save}}.
+#' @param eval.promises
+#' See help of \code{\link[base]{save}}.
+#' @param precheck
+#' See help of \code{\link[base]{save}}.
+#' @return See help of \code{\link[base]{save}}.
+#' @export
+#' @examples
+#' x = 1
+#' save2(y = x, file = tempfile())
+save2 = function(file, ..., ascii = FALSE, version = NULL, compress = !ascii,
+ compression_level, eval.promises = TRUE, precheck = TRUE) {
+ args = tryCatch(as.environment(argsAsNamedList(...)), error = function(e) stopf("Unable to convert to environment (%s)", as.character(e)))
+ save(list = ls(args, all.names = TRUE), envir = args, file = file, ascii = ascii, version = version, compress = compress,
+ compression_level = compression_level, eval.promises = eval.promises, precheck = precheck)
+}
diff --git a/R/seq.R b/R/seq.R
new file mode 100644
index 0000000..59c709e
--- /dev/null
+++ b/R/seq.R
@@ -0,0 +1,22 @@
+#' Generate sequences along rows or cols.
+#'
+#' A simple convenience wrapper around \code{\link[base]{seq_len}}.
+#'
+#' @param x [\code{data.frame} | \code{matrix}]\cr
+#' Data frame, matrix or any object which supports \code{\link[base]{nrow}}
+#' or \code{\link[base]{ncol}}, respectively.
+#' @return Vector of type [\code{integer}].
+#' @export
+#' @examples
+#' data(iris)
+#' seq_row(iris)
+#' seq_col(iris)
+seq_row = function(x) {
+ seq_len(nrow(x))
+}
+
+#' @export seq_col
+#' @rdname seq_row
+seq_col = function(x) {
+ seq_len(ncol(x))
+}
diff --git a/R/setAttribute.R b/R/setAttribute.R
new file mode 100644
index 0000000..8be0c17
--- /dev/null
+++ b/R/setAttribute.R
@@ -0,0 +1,16 @@
+#' A wrapper for \code{attr(x, which) = y}.
+#'
+#' @param x [any]\cr
+#' Your object.
+#' @param which [\code{character(1)}]\cr
+#' Name of the attribute to set
+#' @param value [\code{ANY}]\cr
+#' Value for the attribute.
+#' @return Changed object \code{x}.
+#' @export
+#' @examples
+#' setAttribute(list(), "foo", 1)
+setAttribute = function(x, which, value) {
+ attr(x, which) = value
+ x
+}
diff --git a/R/setClasses.R b/R/setClasses.R
new file mode 100644
index 0000000..e86b17c
--- /dev/null
+++ b/R/setClasses.R
@@ -0,0 +1,14 @@
+#' A wrapper for \code{class(x) = classes}.
+#'
+#' @param x [any]\cr
+#' Your object.
+#' @param classes [\code{character}]\cr
+#' New classes.
+#' @return Changed object \code{x}.
+#' @export
+#' @examples
+#' setClasses(list(), c("foo1", "foo2"))
+setClasses = function(x, classes) {
+ class(x) = classes
+ x
+}
diff --git a/R/setRowColNames.R b/R/setRowColNames.R
new file mode 100644
index 0000000..47b021b
--- /dev/null
+++ b/R/setRowColNames.R
@@ -0,0 +1,21 @@
+#' Wrapper for \code{rownames(x) = y}, \code{colnames(x) = y}.
+#'
+#' @param x [\code{matrix} | \code{data.frame}]\cr
+#' Matrix or data.frame.
+#' @param names [\code{character}]\cr
+#' New names for rows / columns.
+#' @return Changed object \code{x}.
+#' @export
+#' @examples
+#' setColNames(matrix(1:4, 2, 2), c("a", "b"))
+setRowNames = function(x, names) {
+ rownames(x) = names
+ x
+}
+
+#' @rdname setRowNames
+#' @export
+setColNames = function(x, names) {
+ colnames(x) = names
+ x
+}
diff --git a/R/setValue.R b/R/setValue.R
new file mode 100644
index 0000000..38428f1
--- /dev/null
+++ b/R/setValue.R
@@ -0,0 +1,26 @@
+#' Set a list element to a new value.
+#'
+#' This wrapper supports setting elements to \code{NULL}.
+#'
+#' @param obj [\code{list}]\cr
+#' @param index [\code{character} | \code{integer}]\cr
+#' Index or indices where to insert the new values.
+#' @param newval [any]\cr
+#' Inserted elements(s).
+#' Has to be a list if \code{index} is a vector.
+#' @return [\code{list}]
+#' @export
+setValue = function(obj, index, newval) {
+ assertList(obj)
+ assert(checkCharacter(index, any.missing = FALSE), checkIntegerish(index, any.missing = FALSE))
+ if (length(index) == 1L) {
+ if (is.null(newval))
+ obj[index] = list(NULL)
+ else
+ obj[index] = newval
+ } else {
+ assertList(newval, len = length(index))
+ obj[index] = newval
+ }
+ return(obj)
+}
diff --git a/R/sortByCol.R b/R/sortByCol.R
new file mode 100644
index 0000000..07a6114
--- /dev/null
+++ b/R/sortByCol.R
@@ -0,0 +1,30 @@
+#' Sort the rows of a data.frame according to one or more columns.
+#'
+#' @param x [\code{data.frame}]\cr
+#' Data.frame to sort.
+#' @param col [\code{character}]\cr
+#' One or more column names to sort \code{x} by.
+#' In order of preference.
+#' @param asc [\code{logical}]\cr
+#' Sort ascending (or descending)?
+#' One value per entry of \code{col}.
+#' If a scalar logical is passed, it is replicated.
+#' Default is \code{TRUE}.
+#' @return [\code{data.frame}].
+#' @export
+sortByCol = function(x, col, asc = TRUE) {
+ assertDataFrame(x)
+ assertSubset(col, colnames(x))
+ m = length(col)
+ assertLogical(asc, min.len = 1L, any.missing = FALSE)
+ if (length(asc) == 1L)
+ asc = rep(asc, m)
+
+ asc = ifelse(asc, 1, -1)
+ args = as.list(x[, col, drop = FALSE])
+ # convert col to orderable numeric and multiply with factor
+ args = Map(function(a, b) xtfrm(a) * b, args, asc)
+ # now order the numerics and permute df
+ o = do.call(order, args)
+ return(x[o, , drop = FALSE])
+}
diff --git a/R/splitPath.R b/R/splitPath.R
new file mode 100644
index 0000000..86518a9
--- /dev/null
+++ b/R/splitPath.R
@@ -0,0 +1,26 @@
+#' Split a path into components
+#'
+#' The first normalized path is split on forward and backward slashes and its components returned as
+#' character vector. The drive or network home are extracted separately on windows systems and
+#' empty on all other systems.
+#'
+#' @param path [\code{character(1)}]\cr
+#' Path to split as string
+#' @return \code{named list}: List with components \dQuote{drive} (\code{character(1)}
+#' and \dQuote{path} (\code{character(n)}.
+#' @export
+splitPath = function(path) {
+ assertString(path)
+ path = normalizePath(path, mustWork = FALSE)
+ if (isWindows()) {
+ pattern = "^([[:alpha:]]:)|(\\\\[[:alnum:]]+)"
+ m = regexpr(pattern, path)
+ if (length(m) == 1L && m == -1L)
+ stop("Error extracting the drive letter")
+ drive = regmatches(path, m)
+ regmatches(path, m) = ""
+ } else {
+ drive = character(0L)
+ }
+ list(drive = drive, path = Filter(nzchar, strsplit(path, "[/\\]+")[[1L]]))
+}
diff --git a/R/splitTime.R b/R/splitTime.R
new file mode 100644
index 0000000..53cffb9
--- /dev/null
+++ b/R/splitTime.R
@@ -0,0 +1,31 @@
+#' Split seconds into handy chunks of time.
+#'
+#' Note that a year is simply defined as exactly 365 days.
+#'
+#' @param seconds [\code{numeric(1)}]\cr
+#' Number of seconds. If not an integer, it is rounded down.
+#' @param unit [\code{character(1)}]\cr
+#' Largest unit to split seconds into.
+#' Must be one of: \code{c("years", "days", "hours", "minutes", "seconds")}.
+#' Default is \dQuote{years}.
+#' @return [\code{numeric(5)}]. A named vector containing the
+#' \dQuote{years}, \dQuote{days}, \dQuote{hours}, \dQuote{minutes}
+#' and \dQuote{seconds}. Units larger than the given \code{unit} are
+#' \code{NA}.
+#' @export
+#' @examples
+#' splitTime(1000)
+splitTime = function(seconds, unit = "years") {
+ assertNumber(seconds)
+ assertChoice(unit, c("years", "days", "hours", "minutes", "seconds"))
+ divider = c(31536000L, 86400L, 3600L, 60L, 1L)
+ res = setNames(rep.int(NA_integer_, 5L),
+ c("years", "days", "hours", "minutes", "seconds"))
+ start = which(names(res) == unit)
+ for (i in start:length(divider)) {
+ res[i] = seconds %/% divider[i]
+ seconds = seconds - res[i] * divider[i]
+ }
+ ## Make sure all values are integral and do _not_ strip names:
+ viapply(res, as.integer)
+}
diff --git a/R/stopf.R b/R/stopf.R
new file mode 100644
index 0000000..fb1792d
--- /dev/null
+++ b/R/stopf.R
@@ -0,0 +1,25 @@
+#' Wrapper for stop and sprintf.
+#'
+#' A wrapper for \code{\link{stop}} with \code{\link{sprintf}} applied to the arguments.
+#' Notable difference is that error messages are not truncated to 1000 characters
+#' by default.
+#'
+#' @param ... [any]\cr
+#' See \code{\link{sprintf}}.
+#' @param warning.length [\code{integer(1)}]\cr
+#' Number of chars after which the error message
+#' gets truncated, see ?options.
+#' Default is 8170.
+#' @return Nothing.
+#' @export
+#' @examples
+#' err = "an error."
+#' try(stopf("This is %s", err))
+stopf = function(..., warning.length = 8170L) {
+ msg = sprintf(...)
+ obj = simpleError(msg, call = sys.call(sys.parent()))
+ old.opt = getOption("warning.length")
+ on.exit(options(warning.length = old.opt))
+ options(warning.length = warning.length)
+ stop(obj)
+}
diff --git a/R/strrepeat.R b/R/strrepeat.R
new file mode 100644
index 0000000..9d78305
--- /dev/null
+++ b/R/strrepeat.R
@@ -0,0 +1,15 @@
+#' Repeat and join a string
+#'
+#' @param x [character]\cr
+#' Vector of characters.
+#' @param n [\code{integer(1)}]\cr
+#' Times the vector \code{x} is repeated.
+#' @param sep [\code{character(1)}]\cr
+#' Separator to use to collapse the vector of characters.
+#' @return \code{character(1)}.
+#' @export
+#' @examples
+#' strrepeat("x", 3)
+strrepeat = function(x, n, sep = "") {
+ paste0(rep.int(x, n), collapse = sep)
+}
diff --git a/R/suppressAll.R b/R/suppressAll.R
new file mode 100644
index 0000000..3833ea7
--- /dev/null
+++ b/R/suppressAll.R
@@ -0,0 +1,25 @@
+#' Suppresses all output except for errors.
+#'
+#' Evaluates an expression and suppresses all output except for errors,
+#' meaning: prints, messages, warnings and package startup messages.
+#'
+#' @param expr [valid R expression]\cr
+#' Expression.
+#' @return Return value of expression invisibly.
+#' @export
+#' @examples
+#' suppressAll({
+#' print("foo")
+#' message("foo")
+#' warning("foo")
+#' })
+suppressAll = function(expr) {
+ capture.output({
+ z = suppressWarnings(
+ suppressMessages(
+ suppressPackageStartupMessages(force(expr))
+ )
+ )
+ })
+ invisible(z)
+}
diff --git a/R/symdiff.R b/R/symdiff.R
new file mode 100644
index 0000000..83a774d
--- /dev/null
+++ b/R/symdiff.R
@@ -0,0 +1,11 @@
+#' Calculates symmetric set difference between two sets.
+#'
+#' @param x [\code{vector}]\cr
+#' Set 1.
+#' @param y [\code{vector}]\cr
+#' Set 2.
+#' @return [\code{vector}].
+#' @export
+symdiff = function(x, y) {
+ setdiff(union(x, y), intersect(x, y))
+}
diff --git a/R/system3.R b/R/system3.R
new file mode 100644
index 0000000..9c46950
--- /dev/null
+++ b/R/system3.R
@@ -0,0 +1,53 @@
+#' Wrapper for system2 with better return type and errorhandling.
+#'
+#' Wrapper for \code{\link{system2}} with better return type and errorhandling.
+#'
+#' @param command See \code{\link{system2}}.
+#' @param args See \code{\link{system2}}.
+#' @param stdout See \code{\link{system2}}.
+#' @param stderr See \code{\link{system2}}.
+#' @param wait See \code{\link{system2}}.
+#' @param ... Further arguments passed to \code{\link{system2}}.
+#' @param stop.on.exit.code [\code{logical(1)}]\cr
+#' Should an exception be thrown if an exit code greater 0 is generated?
+#' Can only be used if \code{wait} is \code{TRUE}.
+#' Default is \code{wait}.
+#' @return [\code{list}].
+#' \item{exit.code [integer(1)]}{Exit code of command. Given if wait is \code{TRUE}, otherwise \code{NA}. 0L means success. 127L means command was not found}
+#' \item{output [character]}{Output of command on streams. Only given is \code{stdout} or \code{stderr} was set to \code{TRUE}, otherwise \code{NA}.}
+#' @export
+system3 = function(command, args = character(0L), stdout = "", stderr = "", wait = TRUE, ..., stop.on.exit.code = wait) {
+ if (stop.on.exit.code && !wait)
+ stopf("stop.on.exit.code is TRUE but wait is FALSE!")
+ output = NA_character_
+ if (isTRUE(stdout) || isTRUE(stderr)) {
+ wait = TRUE
+ # here we wait anyway and output of cmd is returned
+ ec = 0L
+ suppressWarnings({
+ withCallingHandlers({
+ op = system2(command = command, args = args, stdout = stdout, stderr = stderr, wait = wait, ...)
+ }, warning = function(w) {
+ g = gregexpr("\\d+", w$message)[[1L]]
+ start = tail(g, 1L)
+ len = tail(attr(g, "match.length"), 1L)
+ ec <<- as.integer(substr(w$message, start, start + len - 1L))
+ })
+ })
+ } else {
+ ec = system2(command = command, args = args, stdout = stdout, stderr = stderr, wait = wait, ...)
+ }
+ if (wait) {
+ if (isTRUE(stdout) || isTRUE(stderr))
+ output = op
+ }
+ if (stop.on.exit.code && ec > 0L) {
+ args = collapse(args, " ")
+ if (length(output) == 0L)
+ output = ""
+ else
+ output = collapse(output, "\n")
+ stopf("Command: %s %s; exit code: %i; output: %s", command, args, ec, output)
+ }
+ list(exit.code = ec, output = output)
+}
diff --git a/R/toRangeStr.R b/R/toRangeStr.R
new file mode 100644
index 0000000..628bb8b
--- /dev/null
+++ b/R/toRangeStr.R
@@ -0,0 +1,34 @@
+#' Convert a numerical vector into a range string.
+#'
+#' @param x [\code{integer}]\cr
+#' Vector to convert into a range string.
+#' @param range.sep [\code{character(1)}]\cr
+#' Separator between the first and last element of a range of consecutive
+#' elements in \code{x}.
+#' Default is \dQuote{ - }.
+#' @param block.sep [\code{character(1)}]\cr
+#' Separator between non consecutive elements of \code{x} or ranges.
+#' Default is \dQuote{, }.
+#' @return [\code{character(1)}]
+#' @examples
+#' x = sample(1:10, 7)
+#' toRangeStr(x)
+#' @export
+toRangeStr = function(x, range.sep = " - ", block.sep = ", ") {
+ if (testIntegerish(x))
+ x = as.integer(x)
+ else
+ assertNumeric(x, any.missing = FALSE)
+ assertString(range.sep)
+ assertString(block.sep)
+
+ findRange = function(x) seq_len(max(which(x == x[1L] + 0:(length(x)-1L))))
+ x = sort(unique(x))
+ x = unname(split(x, c(0L, cumsum(diff(x) > 1L))))
+ combine = function(x)
+ if (length(x) == 1L)
+ as.character(x)
+ else
+ sprintf("%i%s%i", x[1L], range.sep, x[length(x)])
+ collapse(vapply(x, combine, character(1L), USE.NAMES = FALSE), block.sep)
+}
diff --git a/R/vapply.R b/R/vapply.R
new file mode 100644
index 0000000..0171400
--- /dev/null
+++ b/R/vapply.R
@@ -0,0 +1,40 @@
+#' Apply a function with a predefined return value
+#'
+#' @description
+#' These are just wrappers around \code{\link[base]{vapply}} with
+#' argument \code{FUN.VALUE} set.
+#' The function is expected to return a single \code{logical}, \code{integer},
+#' \code{numeric} or \code{character} value, depending on the second letter
+#' of the function name.
+#'
+#' @param x [\code{vector} or \code{list}]\cr
+#' Object to apply function on.
+#' @param fun [\code{function}]\cr
+#' Function to apply on each element of \code{x}.
+#' @param ... [\code{ANY}]\cr
+#' Additional arguments for \code{fun}.
+#' @param use.names [\code{logical(1)}]\cr
+#' Should result be named?
+#' Default is \code{TRUE}.
+#' @export
+vlapply = function(x, fun, ..., use.names = TRUE) {
+ vapply(X = x, FUN = fun, ..., FUN.VALUE = NA, USE.NAMES = use.names)
+}
+
+#' @rdname vlapply
+#' @export
+viapply = function(x, fun, ..., use.names = TRUE) {
+ vapply(X = x, FUN = fun, ..., FUN.VALUE = NA_integer_, USE.NAMES = use.names)
+}
+
+#' @rdname vlapply
+#' @export
+vnapply = function(x, fun, ..., use.names = TRUE) {
+ vapply(X = x, FUN = fun, ..., FUN.VALUE = NA_real_, USE.NAMES = use.names)
+}
+
+#' @rdname vlapply
+#' @export
+vcapply = function(x, fun, ..., use.names = TRUE) {
+ vapply(X = x, FUN = fun, ..., FUN.VALUE = NA_character_, USE.NAMES = use.names)
+}
diff --git a/R/warningf.R b/R/warningf.R
new file mode 100644
index 0000000..84ed503
--- /dev/null
+++ b/R/warningf.R
@@ -0,0 +1,31 @@
+#' Wrapper for warning and sprintf.
+#'
+#' A wrapper for \code{\link{warning}} with \code{\link{sprintf}} applied to the arguments.
+#'
+#' @param ... [any]\cr
+#' See \code{\link{sprintf}}.
+#' @param immediate [\code{logical(1)}]\cr
+#' See \code{\link{warning}}.
+#' Default is \code{TRUE}.
+#' @param warning.length [\code{integer(1)}]\cr
+#' Number of chars after which the warning message
+#' gets truncated, see ?options.
+#' Default is 8170.
+#' @return Nothing.
+#' @export
+#' @examples
+#' msg = "a warning"
+#' warningf("this is %s", msg)
+warningf = function(..., immediate = TRUE, warning.length = 8170L) {
+ msg = sprintf(...)
+ if (immediate) {
+ old = getOption("warn")
+ # dont change warn setting if it is 2 (= error)
+ if (old <= 0L) {
+ on.exit(options(warn = old))
+ options(warn = 1L)
+ }
+ }
+ obj = simpleWarning(msg, call = sys.call(sys.parent()))
+ warning(obj)
+}
diff --git a/R/which.first.R b/R/which.first.R
new file mode 100644
index 0000000..c755874
--- /dev/null
+++ b/R/which.first.R
@@ -0,0 +1,23 @@
+#' Find the index of first/last \code{TRUE} value in a logical vector.
+#'
+#' @param x [\code{logical}]\cr
+#' Logical vector.
+#' @param use.names [\code{logical(1)}]\cr
+#' If \code{TRUE} and \code{x} is named, the result is also
+#' named.
+#' @return [\code{integer(1)} | \code{integer(0)}].
+#' Returns the index of the first/last \code{TRUE} value in \code{x} or
+#' an empty integer vector if none is found.
+#' @export
+#' @examples
+#' which.first(c(FALSE, TRUE))
+#' which.last(c(FALSE, FALSE))
+which.first = function(x, use.names = TRUE) {
+ .Call("c_which_first", x, use.names, PACKAGE = "BBmisc")
+}
+
+#' @rdname which.first
+#' @export
+which.last = function(x, use.names = TRUE) {
+ .Call("c_which_last", x, use.names, PACKAGE = "BBmisc")
+}
diff --git a/R/zzz.R b/R/zzz.R
new file mode 100644
index 0000000..68731ef
--- /dev/null
+++ b/R/zzz.R
@@ -0,0 +1,10 @@
+#' @import stats
+#' @import checkmate
+#' @import utils
+#' @importFrom methods is
+
+.onLoad = function(libname, pkgname) {
+ options(BBmisc.ProgressBar.stream = getOption("BBmisc.ProgressBar.stream", "stderr"))
+ options(BBmisc.ProgressBar.style = getOption("BBmisc.ProgressBar.style", "text"))
+ options(BBmisc.ProgressBar.width = getOption("BBmisc.ProgressBar.width", getOption("width")))
+}
diff --git a/R/zzz_deprecated.R b/R/zzz_deprecated.R
new file mode 100644
index 0000000..fa8d642
--- /dev/null
+++ b/R/zzz_deprecated.R
@@ -0,0 +1,24 @@
+#FIXME: remove
+
+#' Deprecated function. Do not use!
+#'
+#' @param df No text
+#' @param chars.as.factor No text
+#' @param factors.as.char No text
+#' @param ints.as.num No text
+#' @param logicals.as.factor No text
+#' @param x No text
+#' @param num.format No text
+#' @param clip.len No text
+#'
+#' @name deprecated
+#' @rdname deprecated
+NULL
+
+#' @export
+#' @rdname deprecated
+convertDfCols = convertDataFrameCols
+
+#' @export
+#' @rdname deprecated
+listToShortString = convertToShortString
diff --git a/debian/README.test b/debian/README.test
deleted file mode 100644
index 3574a58..0000000
--- a/debian/README.test
+++ /dev/null
@@ -1,9 +0,0 @@
-Notes on how this package can be tested.
-────────────────────────────────────────
-
-This package can be tested by running the provided test:
-
-cd tests
-LC_ALL=C R --no-save < run-all.R
-
-in order to confirm its integrity.
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index b63d305..0000000
--- a/debian/changelog
+++ /dev/null
@@ -1,44 +0,0 @@
-r-cran-bbmisc (1.10-2) UNRELEASED; urgency=medium
-
- * Fix Vcs-Browser
- * debhelper 10
- * d/watch: version=4
-
- -- Andreas Tille <tille at debian.org> Sun, 01 Jan 2017 23:57:49 +0100
-
-r-cran-bbmisc (1.10-1) unstable; urgency=medium
-
- * New upstream version
- * Convert to dh-r
- * Canonical homepage for CRAN
- * Versioned Build-Depends: r-cran-checkmate (>= 1.8.0)
-
- -- Andreas Tille <tille at debian.org> Fri, 04 Nov 2016 12:02:23 +0100
-
-r-cran-bbmisc (1.9-2) unstable; urgency=medium
-
- * Fix missing test depencency r-cran-codetools
- * cme fix dpkg-control
-
- -- Andreas Tille <tille at debian.org> Wed, 27 Apr 2016 21:06:19 +0200
-
-r-cran-bbmisc (1.9-1) unstable; urgency=medium
-
- * New upstream version
- * cme fix dpkg-control
- * DEP5 name
-
- -- Andreas Tille <tille at debian.org> Sat, 27 Jun 2015 11:02:19 +0200
-
-r-cran-bbmisc (1.7-1) unstable; urgency=medium
-
- * New upstream version
- * (Build-)Depends: r-cran-checkmate
-
- -- Andreas Tille <tille at debian.org> Fri, 11 Jul 2014 23:00:32 +0200
-
-r-cran-bbmisc (1.6-1) unstable; urgency=low
-
- * Initial release (Closes: #751543)
-
- -- Andreas Tille <tille at debian.org> Fri, 13 Jun 2014 22:52:06 +0200
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index f599e28..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-10
diff --git a/debian/control b/debian/control
deleted file mode 100644
index 8594fd0..0000000
--- a/debian/control
+++ /dev/null
@@ -1,24 +0,0 @@
-Source: r-cran-bbmisc
-Maintainer: Debian Med Packaging Team <debian-med-packaging at lists.alioth.debian.org>
-Uploaders: Andreas Tille <tille at debian.org>
-Section: gnu-r
-Priority: optional
-Build-Depends: debhelper (>= 10),
- dh-r,
- r-base-dev (>= 3.0.0),
- r-cran-checkmate (>= 1.8.0)
-Standards-Version: 3.9.8
-Vcs-Browser: https://anonscm.debian.org/viewvc/debian-med/trunk/packages/R/r-cran-bbmisc/trunk/
-Vcs-Svn: svn://anonscm.debian.org/debian-med/trunk/packages/R/r-cran-bbmisc/trunk/
-Homepage: https://cran.r-project.org/package=BBmisc
-
-Package: r-cran-bbmisc
-Architecture: any
-Depends: ${shlibs:Depends},
- ${misc:Depends},
- ${R:Depends}
-Recommends: ${R:Recommends}
-Suggests: ${R:Suggests}
-Description: GNU R Miscellaneous helper functions for B. Bischl
- Miscellaneous helper functions for and from B. Bischl and some other
- guys at TU Dortmund, mainly for package development.
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644
index f245714..0000000
--- a/debian/copyright
+++ /dev/null
@@ -1,42 +0,0 @@
-Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
-Upstream-Name: BBmisc
-Upstream-Contact: Bernd Bischl <bernd_bischl at gmx.net>
-Source: https://cran.r-project.org/package=BBmisc
-
-Files: *
-Copyright: 2012-2016 Bernd Bischl, Michel Lang, Olaf Mersmann
-License: BSD-3-clause
-
-Files: debian/*
-Copyright: 2014-2016 Andreas Tille <tille at debian.org>
-License: BSD-3-clause
-
-License: BSD-3-clause
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
- .
- Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- .
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
- .
- Neither the name of the <ORGANIZATION> nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
- .
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/debian/docs b/debian/docs
deleted file mode 100644
index 960011c..0000000
--- a/debian/docs
+++ /dev/null
@@ -1,3 +0,0 @@
-tests
-debian/README.test
-debian/tests/run-unit-test
diff --git a/debian/rules b/debian/rules
deleted file mode 100755
index ae86733..0000000
--- a/debian/rules
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/make -f
-
-%:
- dh $@ --buildsystem R
-
-override_dh_install:
- dh_install
- find debian -name LICENSE -delete
diff --git a/debian/source/format b/debian/source/format
deleted file mode 100644
index 163aaf8..0000000
--- a/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/debian/tests/control b/debian/tests/control
deleted file mode 100644
index 6d31b5f..0000000
--- a/debian/tests/control
+++ /dev/null
@@ -1,3 +0,0 @@
-Tests: run-unit-test
-Depends: @, r-cran-testthat, r-cran-codetools
-Restrictions: allow-stderr
diff --git a/debian/tests/run-unit-test b/debian/tests/run-unit-test
deleted file mode 100644
index 38b4942..0000000
--- a/debian/tests/run-unit-test
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh -e
-
-pkg=r-cran-bbmisc
-if [ "$ADTTMP" = "" ] ; then
- ADTTMP=`mktemp -d /tmp/${pkg}-test.XXXXXX`
-fi
-cd $ADTTMP
-cp -a /usr/share/doc/${pkg}/tests/* $ADTTMP
-gunzip -r *
-LC_ALL=C R --no-save < run-all.R
-rm -fr $ADTTMP/*
diff --git a/debian/watch b/debian/watch
deleted file mode 100644
index 700aa76..0000000
--- a/debian/watch
+++ /dev/null
@@ -1,2 +0,0 @@
-version=4
-http://cran.r-project.org/src/contrib/BBmisc_([-\d.]*)\.tar\.gz
diff --git a/man/addClasses.Rd b/man/addClasses.Rd
new file mode 100644
index 0000000..cec3901
--- /dev/null
+++ b/man/addClasses.Rd
@@ -0,0 +1,25 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/addClasses.R
+\name{addClasses}
+\alias{addClasses}
+\title{A wrapper to add to the class attribute.}
+\usage{
+addClasses(x, classes)
+}
+\arguments{
+\item{x}{[any]\cr
+Your object.}
+
+\item{classes}{[\code{character}]\cr
+Classes to add. Will be added in front (specialization).}
+}
+\value{
+Changed object \code{x}.
+}
+\description{
+A wrapper to add to the class attribute.
+}
+\examples{
+addClasses(list(), c("foo1", "foo2"))
+}
+
diff --git a/man/argsAsNamedList.Rd b/man/argsAsNamedList.Rd
new file mode 100644
index 0000000..b69889b
--- /dev/null
+++ b/man/argsAsNamedList.Rd
@@ -0,0 +1,23 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/argsAsNamedList.R
+\name{argsAsNamedList}
+\alias{argsAsNamedList}
+\title{Parses \code{...} arguments to a named list.}
+\usage{
+argsAsNamedList(...)
+}
+\arguments{
+\item{...}{Arbitrary number of objects.}
+}
+\value{
+[\code{list}]: Named list with objects.
+}
+\description{
+The deparsed name will be used for arguments with missing names.
+Missing names will be set to \code{NA}.
+}
+\examples{
+z = 3
+argsAsNamedList(x = 1, y = 2, z)
+}
+
diff --git a/man/asMatrixCols.Rd b/man/asMatrixCols.Rd
new file mode 100644
index 0000000..4880b84
--- /dev/null
+++ b/man/asMatrixCols.Rd
@@ -0,0 +1,30 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/asMatrix.R
+\name{asMatrixCols}
+\alias{asMatrixCols}
+\alias{asMatrixRows}
+\title{Extracts a named element from a list of lists.}
+\usage{
+asMatrixCols(xs, row.names, col.names)
+
+asMatrixRows(xs, row.names, col.names)
+}
+\arguments{
+\item{xs}{[\code{list}]\cr
+A list of vectors of the same length.}
+
+\item{row.names}{[\code{character} | \code{integer} | \code{NULL}]\cr
+Row names of result.
+Default is to take the names of the elements of \code{xs}.}
+
+\item{col.names}{[\code{character} | \code{integer} | \code{NULL}]\cr
+Column names of result.
+Default is to take the names of the elements of \code{xs}.}
+}
+\value{
+[\code{matrix}].
+}
+\description{
+Extracts a named element from a list of lists.
+}
+
diff --git a/man/asQuoted.Rd b/man/asQuoted.Rd
new file mode 100644
index 0000000..a4081ca
--- /dev/null
+++ b/man/asQuoted.Rd
@@ -0,0 +1,27 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/asQuoted.R
+\name{asQuoted}
+\alias{asQuoted}
+\title{Converts a string into a quoted expression.}
+\usage{
+asQuoted(s, env = parent.frame())
+}
+\arguments{
+\item{s}{[\code{character(1)}]\cr
+Expression as string.}
+
+\item{env}{[\code{numeric(1)}]\cr
+Environment for expression.
+Default is \code{parent.frame()}}
+}
+\value{
+Quoted expression.
+}
+\description{
+Works the same as if you would have entered the expression and called
+\code{\link{quote}} on it.
+}
+\examples{
+asQuoted("x == 3")
+}
+
diff --git a/man/binPack.Rd b/man/binPack.Rd
new file mode 100644
index 0000000..ad5056d
--- /dev/null
+++ b/man/binPack.Rd
@@ -0,0 +1,37 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/binPack.R
+\name{binPack}
+\alias{binPack}
+\title{Simple bin packing.}
+\usage{
+binPack(x, capacity)
+}
+\arguments{
+\item{x}{[\code{numeric}]\cr
+Numeric vector of elements to group.}
+
+\item{capacity}{[\code{numeric(1)}]\cr
+Maximum capacity of each bin, i.e., elements will be grouped
+so their sum does not exceed this limit.}
+}
+\value{
+[\code{integer}]. Integer with values \dQuote{1} to \dQuote{n.bins}
+ indicating bin membership.
+}
+\description{
+Maps numeric items in \code{x} into groups with sum
+less or equal than \code{capacity}.
+A very simple greedy algorithm is used, which is not really optimized
+for speed. This is a convenience function for smaller vectors, not
+a competetive solver for the real binbacking problem.
+If an element of \code{x} exceeds \code{capacity}, an error
+is thrown.
+}
+\examples{
+x = 1:10
+bp = binPack(x, 11)
+xs = split(x, bp)
+print(xs)
+print(sapply(xs, sum))
+}
+
diff --git a/man/btwn.Rd b/man/btwn.Rd
new file mode 100644
index 0000000..8d71f14
--- /dev/null
+++ b/man/btwn.Rd
@@ -0,0 +1,27 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/btwn.R
+\name{\%btwn\%}
+\alias{\%btwn\%}
+\title{Check if some values are covered by the range of the values in a second vector.}
+\usage{
+x \%btwn\% y
+}
+\arguments{
+\item{x}{[\code{numeric(n)}]\cr
+Value(s) that should be within the range of \code{y}.}
+
+\item{y}{[\code{numeric}]\cr
+Numeric vector which defines the range.}
+}
+\value{
+[\code{logical(n)}]. For each value in \code{x}: Is it in the range of \code{y}?
+}
+\description{
+Check if some values are covered by the range of the values in a second vector.
+}
+\examples{
+x = 3
+y = c(-1,2,5)
+x \%btwn\% y
+}
+
diff --git a/man/cFactor.Rd b/man/cFactor.Rd
new file mode 100644
index 0000000..0923b1b
--- /dev/null
+++ b/man/cFactor.Rd
@@ -0,0 +1,26 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/factor.R
+\name{cFactor}
+\alias{cFactor}
+\title{Combine multiple factors and return a factor.}
+\usage{
+cFactor(...)
+}
+\arguments{
+\item{...}{[\code{factor}]\cr
+The factors.}
+}
+\value{
+[\code{factor}].
+}
+\description{
+Note that function does not inherit from \code{\link{c}} to not change R semantics behind your back when this
+package is loaded.
+}
+\examples{
+f1 = factor(c("a", "b"))
+f2 = factor(c("b", "c"))
+print(c(f1, f2))
+print(cFactor(f1, f2))
+}
+
diff --git a/man/capitalizeStrings.Rd b/man/capitalizeStrings.Rd
new file mode 100644
index 0000000..64eb148
--- /dev/null
+++ b/man/capitalizeStrings.Rd
@@ -0,0 +1,32 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/capitalizeStrings.R
+\name{capitalizeStrings}
+\alias{capitalizeStrings}
+\title{Capitalize strings in a vector}
+\usage{
+capitalizeStrings(x, all.words = FALSE, lower.back = FALSE)
+}
+\arguments{
+\item{x}{[\code{character(n)}]\cr
+Vector of character elements to capitalize.}
+
+\item{all.words}{[\code{logical(1)}]\cr
+If \code{TRUE} all words of each vector element are capitalized.
+\code{FALSE} capitalizes the first word of each vector element.}
+
+\item{lower.back}{[\code{logical(1)}]\cr
+\code{TRUE} lowers the back of each word or vector element (depends on \code{all.words}).}
+}
+\value{
+Capitalized vector: [\code{character(n)}].
+}
+\description{
+Capitalise first word or all words of a character vector.
+Lower back of vector element or word, respectively.
+}
+\examples{
+capitalizeStrings(c("the taIl", "wags The dOg", "That looks fuNny!"))
+capitalizeStrings(c("the taIl", "wags The dOg", "That looks fuNny!")
+, all.words = TRUE, lower.back = TRUE)
+}
+
diff --git a/man/catf.Rd b/man/catf.Rd
new file mode 100644
index 0000000..a60164d
--- /dev/null
+++ b/man/catf.Rd
@@ -0,0 +1,35 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/catf.R
+\name{catf}
+\alias{catf}
+\title{Wrapper for cat and sprintf.}
+\usage{
+catf(..., file = "", append = FALSE, newline = TRUE)
+}
+\arguments{
+\item{...}{[any]\cr
+See \code{\link{sprintf}}.}
+
+\item{file}{[\code{character(1)}]\cr
+See \code{\link{cat}}.
+Default is \dQuote{}.}
+
+\item{append}{[\code{logical(1)}]\cr
+See \code{\link{cat}}.
+Default is \code{FALSE}.}
+
+\item{newline}{[\code{logical(1)}]\cr
+Append newline at the end?
+Default is \code{TRUE}.}
+}
+\value{
+Nothing.
+}
+\description{
+A simple wrapper for \code{cat(sprintf(...))}.
+}
+\examples{
+msg = "a message."
+catf("This is \%s", msg)
+}
+
diff --git a/man/checkArg.Rd b/man/checkArg.Rd
new file mode 100644
index 0000000..9aacc6a
--- /dev/null
+++ b/man/checkArg.Rd
@@ -0,0 +1,85 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkArg.R
+\name{checkArg}
+\alias{checkArg}
+\title{Check for a function argument.}
+\usage{
+checkArg(x, cl, s4 = FALSE, len, min.len, max.len, choices, subset,
+ lower = NA, upper = NA, na.ok = TRUE, formals)
+}
+\arguments{
+\item{x}{[any]\cr
+Argument.}
+
+\item{cl}{[\code{character}]\cr
+Class that argument must \dQuote{inherit} from.
+If multiple classes are given, \code{x} must \dQuote{inherit} from at least one of these.
+See also argument \code{s4}.}
+
+\item{s4}{[\code{logical(1)}]\cr
+If \code{TRUE}, use \code{is} for checking class \code{cl}, otherwise use \code{\link{inherits}}, which
+implies that only S3 classes are correctly checked. This is done for speed reasons
+as calling \code{\link{is}} is pretty slow.
+Default is \code{FALSE}.}
+
+\item{len}{[\code{integer(1)}]\cr
+Length that argument must have.
+Not checked if not passed, which is the default.}
+
+\item{min.len}{[\code{integer(1)}]\cr
+Minimal length that argument must have.
+Not checked if not passed, which is the default.}
+
+\item{max.len}{[\code{integer(1)}]\cr
+Maximal length that argument must have.
+Not checked if not passed, which is the default.}
+
+\item{choices}{[any]\cr
+Discrete number of choices, expressed by a vector of R objects.
+If passed, argument must be identical to one of these and nothing else is checked.}
+
+\item{subset}{[any]\cr
+Discrete number of choices, expressed by a vector of R objects.
+If passed, argument must be identical to a subset of these and nothing else is checked.}
+
+\item{lower}{[\code{numeric(1)}]\cr
+Lower bound for numeric vector arguments.
+Default is \code{NA}, which means not required.}
+
+\item{upper}{[\code{numeric(1)}]\cr
+Upper bound for numeric vector arguments.
+Default is \code{NA}, which means not required.}
+
+\item{na.ok}{[\code{logical(1)}]\cr
+Is it ok if a vector argument contains NAs?
+Default is \code{TRUE}.}
+
+\item{formals}{[\code{character}]\cr
+If this is passed, \code{x} must be a function.
+It is then checked that \code{formals} are the names of the
+(first) formal arguments in the signature of \code{x}.
+Meaning \code{checkArg(function(a, b), formals = "a")} is ok.
+Default is missing.}
+}
+\value{
+Nothing.
+}
+\description{
+Throws exception if checks are not passed.
+Note that argument is evaluated when checked.
+}
+\examples{
+x = 1L
+checkArg(x, "integer", len = 1, na.ok = FALSE, upper = 3L)
+x = as.integer(NA)
+checkArg(x, "integer", len = 1, na.ok = TRUE)
+x = c("foo", "bar")
+checkArg(x, "character")
+x = "foo"
+checkArg(x, choices = c("foo", "bar"))
+x = c("foo", "bar")
+checkArg(x, subset = c("foo", "bar"))
+fun = function(foo, bar)
+checkArg(fun, formals = c("foo", "bar"))
+}
+
diff --git a/man/checkListElementClass.Rd b/man/checkListElementClass.Rd
new file mode 100644
index 0000000..24730cd
--- /dev/null
+++ b/man/checkListElementClass.Rd
@@ -0,0 +1,28 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkListElementClass.R
+\name{checkListElementClass}
+\alias{checkListElementClass}
+\title{Check that a list contains only elements of a required type.}
+\usage{
+checkListElementClass(xs, cl)
+}
+\arguments{
+\item{xs}{[\code{list}]\cr
+Argument.}
+
+\item{cl}{[\code{character(1)}]\cr
+Class that elements must have. Checked with \code{is}.}
+}
+\value{
+Nothing.
+}
+\description{
+Check that argument is a list and contains only elements of a required type.
+Throws exception if check is not passed.
+Note that argument is evaluated when checked.
+}
+\examples{
+xs = as.list(1:3)
+checkListElementClass(xs, "numeric")
+}
+
diff --git a/man/chunk.Rd b/man/chunk.Rd
new file mode 100644
index 0000000..e341d00
--- /dev/null
+++ b/man/chunk.Rd
@@ -0,0 +1,49 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/chunk.R
+\name{chunk}
+\alias{chunk}
+\title{Chunk elements of vectors into blocks of nearly equal size.}
+\usage{
+chunk(x, chunk.size, n.chunks, props, shuffle = FALSE)
+}
+\arguments{
+\item{x}{[ANY]\cr
+Vector, list or other type supported by \code{\link[base]{split}}.}
+
+\item{chunk.size}{[\code{integer(1)}]\cr
+Requested number of elements in each chunk.
+Cannot be used in combination with \code{n.chunks} or \code{props}.
+If \code{x} cannot be evenly chunked, some chunks will have less elements.}
+
+\item{n.chunks}{[\code{integer(1)}]\cr
+Requested number of chunks.
+If more chunks than elements in \code{x} are requested, empty chunks are
+dropped.
+Can not be used in combination with \code{chunks.size} or \code{props}.}
+
+\item{props}{[\code{numeric}]\cr
+Vector of proportions for chunk sizes.
+Empty chunks may occur, depending on the length of \code{x} and the given
+proportions.
+Cannot be used in combination with \code{chunks.size} or \code{n.chunks}.}
+
+\item{shuffle}{[\code{logical(1)}]\cr
+Shuffle \code{x}?
+Default is \code{FALSE}.}
+}
+\value{
+[unnamed \code{list}] of chunks.
+}
+\description{
+In case of shuffling and vectors that cannot be chunked evenly,
+it is chosen randomly which levels / chunks will receive 1 element less.
+If you do not shuffle, always the last chunks will receive 1 element less.
+}
+\examples{
+xs = 1:10
+chunk(xs, chunk.size = 3)
+chunk(xs, n.chunks = 2)
+chunk(xs, n.chunks = 2, shuffle = TRUE)
+chunk(xs, props = c(7, 3))
+}
+
diff --git a/man/clipString.Rd b/man/clipString.Rd
new file mode 100644
index 0000000..e1e1c28
--- /dev/null
+++ b/man/clipString.Rd
@@ -0,0 +1,31 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/clipString.R
+\name{clipString}
+\alias{clipString}
+\title{Shortens strings to a given length.}
+\usage{
+clipString(x, len, tail = "...")
+}
+\arguments{
+\item{x}{[\code{character}]\cr
+Vector of strings.}
+
+\item{len}{[\code{integer(1)}]\cr
+Absolute length the string should be clipped to, including \code{tail}.
+Note that you cannot clip to a shorter length than \code{tail}.}
+
+\item{tail}{[\code{character(1)}]\cr
+If the string has to be shortened at least 1 character, the final characters will be \code{tail}.
+Default is \dQuote{...}.}
+}
+\value{
+[\code{character(1)}].
+}
+\description{
+Shortens strings to a given length.
+}
+\examples{
+print(clipString("abcdef", 10))
+print(clipString("abcdef", 5))
+}
+
diff --git a/man/coalesce.Rd b/man/coalesce.Rd
new file mode 100644
index 0000000..b854624
--- /dev/null
+++ b/man/coalesce.Rd
@@ -0,0 +1,26 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/coalesce.R
+\name{coalesce}
+\alias{coalesce}
+\title{Returns first non-missing, non-null argument.}
+\usage{
+coalesce(...)
+}
+\arguments{
+\item{...}{[any]\cr
+Arguments.}
+}
+\value{
+[any].
+}
+\description{
+Returns first non-missing, non-null argument, otherwise
+\code{NULL}.
+}
+\examples{
+f = function(x,y) {
+ print(coalesce(NULL, x, y))
+}
+f(y = 3)
+}
+
diff --git a/man/collapse.Rd b/man/collapse.Rd
new file mode 100644
index 0000000..ba56687
--- /dev/null
+++ b/man/collapse.Rd
@@ -0,0 +1,27 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/collapse.R
+\name{collapse}
+\alias{collapse}
+\title{Collapse vector to string.}
+\usage{
+collapse(x, sep = ",")
+}
+\arguments{
+\item{x}{[\code{vector}]\cr
+Vector to collapse.}
+
+\item{sep}{[\code{character(1)}]\cr
+Passed to \code{collapse} in \code{\link{paste}}.
+Default is \dQuote{,}.}
+}
+\value{
+[\code{character(1)}].
+}
+\description{
+A simple wrapper for \code{paste(x, collapse)}.
+}
+\examples{
+collapse(c("foo", "bar"))
+collapse(c("foo", "bar"), sep = ";")
+}
+
diff --git a/man/collapsef.Rd b/man/collapsef.Rd
new file mode 100644
index 0000000..56d445d
--- /dev/null
+++ b/man/collapsef.Rd
@@ -0,0 +1,25 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/collapsef.R
+\name{collapsef}
+\alias{collapsef}
+\title{Collapse vector to string.}
+\usage{
+collapsef(..., sep = ",")
+}
+\arguments{
+\item{...}{[any]\cr
+See \code{\link{sprintf}}.}
+
+\item{sep}{[\code{character(1)}]\cr
+See \code{\link{collapse}}.}
+}
+\value{
+[\code{character(1)}].
+}
+\description{
+A simple wrapper for \code{collapse(sprintf, ...)}.
+}
+\details{
+Useful for vectorized call to \code{\link{sprintf}}.
+}
+
diff --git a/man/computeMode.Rd b/man/computeMode.Rd
new file mode 100644
index 0000000..8543a3d
--- /dev/null
+++ b/man/computeMode.Rd
@@ -0,0 +1,33 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/computeMode.R
+\name{computeMode}
+\alias{computeMode}
+\title{Compute statistical mode of a vector (value that occurs most frequently).}
+\usage{
+computeMode(x, ties.method = "random", na.rm = TRUE)
+}
+\arguments{
+\item{x}{[\code{vector}]\cr
+Factor, character, integer, numeric or logical vector.}
+
+\item{ties.method}{[\code{character(1)}]\cr
+\dQuote{first}, \dQuote{random}, \dQuote{last}: Decide which value to take in case of ties.
+Default is \dQuote{random}.}
+
+\item{na.rm}{[\code{logical(1)}]\cr
+If \code{TRUE}, missing values in the data removed.
+if \code{FALSE}, they are used as a separate level and this level could therefore
+be returned as the most frequent one.
+Default is \code{TRUE}.}
+}
+\value{
+Modal value of length 1, data type depends on data type of \code{x}.
+}
+\description{
+Works for integer, numeric, factor and character vectors.
+The implementation is currently not extremely efficient.
+}
+\examples{
+computeMode(c(1,2,3,3))
+}
+
diff --git a/man/convertDataFrameCols.Rd b/man/convertDataFrameCols.Rd
new file mode 100644
index 0000000..e5a6c35
--- /dev/null
+++ b/man/convertDataFrameCols.Rd
@@ -0,0 +1,36 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/convertDataFrameCols.R
+\name{convertDataFrameCols}
+\alias{convertDataFrameCols}
+\title{Converts columns in a data frame to characters, factors or numerics.}
+\usage{
+convertDataFrameCols(df, chars.as.factor = FALSE, factors.as.char = FALSE,
+ ints.as.num = FALSE, logicals.as.factor = FALSE)
+}
+\arguments{
+\item{df}{[\code{data.frame}]\cr
+Data frame.}
+
+\item{chars.as.factor}{[\code{logical(1)}]\cr
+Should characters be converted to factors?
+Default is \code{FALSE}.}
+
+\item{factors.as.char}{[\code{logical(1)}]\cr
+Should characters be converted to factors?
+Default is \code{FALSE}.}
+
+\item{ints.as.num}{[\code{logical(1)}]\cr
+Should integers be converted to numerics?
+Default is \code{FALSE}.}
+
+\item{logicals.as.factor}{[\code{logical(1)}]\cr
+Should logicals be converted to factors?
+Default is \code{FALSE}.}
+}
+\value{
+[\code{data.frame}].
+}
+\description{
+Converts columns in a data frame to characters, factors or numerics.
+}
+
diff --git a/man/convertInteger.Rd b/man/convertInteger.Rd
new file mode 100644
index 0000000..4804949
--- /dev/null
+++ b/man/convertInteger.Rd
@@ -0,0 +1,27 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/convertInteger.R
+\name{convertInteger}
+\alias{convertInteger}
+\title{Conversion for single integer.}
+\usage{
+convertInteger(x)
+}
+\arguments{
+\item{x}{[any]\cr
+Argument.}
+}
+\value{
+Either a single integer if conversion was done or \code{x} unchanged.
+}
+\description{
+Convert single numeric to integer only if the numeric represents a single integer,
+e.g. 1 to 1L.
+Otherwise the argument is returned unchanged.
+}
+\examples{
+str(convertInteger(1.0))
+str(convertInteger(1.3))
+str(convertInteger(c(1.0, 2.0)))
+str(convertInteger("foo"))
+}
+
diff --git a/man/convertIntegers.Rd b/man/convertIntegers.Rd
new file mode 100644
index 0000000..2890665
--- /dev/null
+++ b/man/convertIntegers.Rd
@@ -0,0 +1,28 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/convertInteger.R
+\name{convertIntegers}
+\alias{convertIntegers}
+\title{Conversion for integer vector.}
+\usage{
+convertIntegers(x)
+}
+\arguments{
+\item{x}{[any]\cr
+Argument.}
+}
+\value{
+Either an integer vector if conversion was done or \code{x} unchanged.
+}
+\description{
+Convert numeric vector to integer vector if the numeric vector fully represents
+an integer vector,
+e.g. \code{c(1, 5)} to \code{c(1L, 5L)}.
+Otherwise the argument is returned unchanged.
+}
+\examples{
+str(convertIntegers(1.0))
+str(convertIntegers(1.3))
+str(convertIntegers(c(1.0, 2.0)))
+str(convertIntegers("foo"))
+}
+
diff --git a/man/convertListOfRowsToDataFrame.Rd b/man/convertListOfRowsToDataFrame.Rd
new file mode 100644
index 0000000..49c3420
--- /dev/null
+++ b/man/convertListOfRowsToDataFrame.Rd
@@ -0,0 +1,38 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/convertListOfRowsToDataFrame.R
+\name{convertListOfRowsToDataFrame}
+\alias{convertListOfRowsToDataFrame}
+\title{Convert a list of row-vectors of equal structure to a data.frame.}
+\usage{
+convertListOfRowsToDataFrame(rows,
+ strings.as.factors = default.stringsAsFactors(), row.names, col.names)
+}
+\arguments{
+\item{rows}{[\code{list}]\cr
+List of rows. Each row is a list or vector of the same structure.
+That means all rows must have the same length and all corresponding elements must have the
+same class.}
+
+\item{strings.as.factors}{[\code{logical(1)}]\cr
+Convert character columns to factors?
+Default is \code{default.stringsAsFactors()}.}
+
+\item{row.names}{[\code{character} | \code{integer} | \code{NULL}]\cr
+Row names for result.
+By default the names of the list \code{rows} are taken.}
+
+\item{col.names}{[\code{character} | \code{integer}]\cr
+Column names for result.
+By default the names of an element of \code{rows} are taken.}
+}
+\value{
+[\code{data.frame}].
+}
+\description{
+Elements are arranged in columns according to their name in each
+element of \code{rows}. Missing values are filled using NAs.
+}
+\examples{
+convertListOfRowsToDataFrame(list(list(x = 1, y = "a"), list(x = 2, y = "b")))
+}
+
diff --git a/man/convertMatrixType.Rd b/man/convertMatrixType.Rd
new file mode 100644
index 0000000..f4109bf
--- /dev/null
+++ b/man/convertMatrixType.Rd
@@ -0,0 +1,25 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/convertMatrixType.R
+\name{convertMatrixType}
+\alias{convertMatrixType}
+\title{Converts storage type of a matrix.}
+\usage{
+convertMatrixType(x, type)
+}
+\arguments{
+\item{x}{[\code{matrix}]\cr.
+Matrix to convert.}
+
+\item{type}{[\code{character(1)}]\cr
+New storage type.}
+}
+\value{
+[\code{matrix}].
+}
+\description{
+Works by setting \code{\link{mode}}.
+}
+\note{
+\code{as.mytype} drops dimension when used on a matrix.
+}
+
diff --git a/man/convertRowsToList.Rd b/man/convertRowsToList.Rd
new file mode 100644
index 0000000..00e34b3
--- /dev/null
+++ b/man/convertRowsToList.Rd
@@ -0,0 +1,42 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/convertRowsToList.R
+\name{convertRowsToList}
+\alias{convertColsToList}
+\alias{convertRowsToList}
+\title{Convert rows (columns) of data.frame or matrix to lists.}
+\usage{
+convertRowsToList(x, name.list = TRUE, name.vector = FALSE,
+ factors.as.char = TRUE, as.vector = TRUE)
+
+convertColsToList(x, name.list = FALSE, name.vector = FALSE,
+ factors.as.char = TRUE, as.vector = TRUE)
+}
+\arguments{
+\item{x}{[\code{matrix} | \code{data.frame}]\cr
+Object to convert.}
+
+\item{name.list}{[\code{logical(1)}]\cr
+Name resulting list with names of rows (cols) of \code{x}?
+Default is \code{FALSE}.}
+
+\item{name.vector}{[\code{logical(1)}]\cr
+Name vector elements in resulting list with names of cols (rows) of \code{x}?
+Default is \code{FALSE}.}
+
+\item{factors.as.char}{[\code{logical(1)}]\cr
+If \code{x} is a data.frame, convert factor columns to
+string elements in the resulting lists?
+Default is \code{TRUE}.}
+
+\item{as.vector}{[\code{logical(1)}]\cr
+If \code{x} is a matrix, store rows as vectors in the resulting list - or otherwise as lists?
+Default is \code{TRUE}.}
+}
+\value{
+[\code{list} of lists or vectors].
+}
+\description{
+For each row, one list/vector is constructed, each entry of
+the row becomes a list/vector element.
+}
+
diff --git a/man/convertToShortString.Rd b/man/convertToShortString.Rd
new file mode 100644
index 0000000..a3a0033
--- /dev/null
+++ b/man/convertToShortString.Rd
@@ -0,0 +1,40 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/convertToShortString.R
+\name{convertToShortString}
+\alias{convertToShortString}
+\title{Converts any R object to a descriptive string so it can be used in messages.}
+\usage{
+convertToShortString(x, num.format = "\%.4g", clip.len = 15L)
+}
+\arguments{
+\item{x}{[any]\cr
+The object.}
+
+\item{num.format}{[\code{character(1)}]\cr
+Used to format numerical scalars via \code{\link{sprintf}}.
+Default is \dQuote{\%.4g}.}
+
+\item{clip.len}{[\code{integer(1)}]\cr
+Used clip atomic vectors via \code{\link{clipString}}.
+Default is 15.}
+}
+\value{
+[\code{character(1)}].
+}
+\description{
+Atomics: If of length 0 or 1, they are basically printed as they are.
+Numerics are formated with \code{num.format}.
+If of length greater than 1, they are collapsed witd \dQuote{,} and clipped.
+so they do not become excessively long.
+
+All others: Currently, only their class is simply printed
+like \dQuote{<data.frame>}.
+
+Lists: The mechanism above is applied (non-recursively) to their elements.
+The result looks like this:
+\dQuote{a = 1, <unamed> = 2, b = <data.frame>, c = <list>}.
+}
+\examples{
+convertToShortString(list(a = 1, b = NULL, "foo", c = 1:10))
+}
+
diff --git a/man/dapply.Rd b/man/dapply.Rd
new file mode 100644
index 0000000..17b086f
--- /dev/null
+++ b/man/dapply.Rd
@@ -0,0 +1,32 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/dapply.R
+\name{dapply}
+\alias{dapply}
+\title{Call \code{lapply} on an object and return a data.frame.}
+\usage{
+dapply(x, fun, ..., col.names)
+}
+\arguments{
+\item{x}{[\code{data.frame}]\cr
+Data frame.}
+
+\item{fun}{[\code{function}]\cr
+The function to apply.}
+
+\item{...}{[any]\cr
+Further arguments passed down to \code{fun}.}
+
+\item{col.names}{[\code{character(1)}]\cr
+Column names for result.
+Default are the names of \code{x}.}
+}
+\value{
+[\code{data.frame}].
+}
+\description{
+Applies a function \code{fun} on each element of input \code{x}
+and combines the results as \code{data.frame} columns.
+The results will get replicated to have equal length
+if necessary and possible.
+}
+
diff --git a/man/deprecated.Rd b/man/deprecated.Rd
new file mode 100644
index 0000000..c7fddb8
--- /dev/null
+++ b/man/deprecated.Rd
@@ -0,0 +1,34 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/zzz_deprecated.R
+\name{deprecated}
+\alias{convertDfCols}
+\alias{deprecated}
+\alias{listToShortString}
+\title{Deprecated function. Do not use!}
+\usage{
+convertDfCols(df, chars.as.factor = FALSE, factors.as.char = FALSE,
+ ints.as.num = FALSE, logicals.as.factor = FALSE)
+
+listToShortString(x, num.format = "\%.4g", clip.len = 15L)
+}
+\arguments{
+\item{df}{No text}
+
+\item{chars.as.factor}{No text}
+
+\item{factors.as.char}{No text}
+
+\item{ints.as.num}{No text}
+
+\item{logicals.as.factor}{No text}
+
+\item{x}{No text}
+
+\item{num.format}{No text}
+
+\item{clip.len}{No text}
+}
+\description{
+Deprecated function. Do not use!
+}
+
diff --git a/man/do.call2.Rd b/man/do.call2.Rd
new file mode 100644
index 0000000..97bb930
--- /dev/null
+++ b/man/do.call2.Rd
@@ -0,0 +1,36 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/do.call2.R
+\name{do.call2}
+\alias{do.call2}
+\title{Execute a function call similar to \code{do.call}.}
+\usage{
+do.call2(fun, ..., .args = list())
+}
+\arguments{
+\item{fun}{[\code{character(1)}]\cr
+Name of the function to call.}
+
+\item{...}{[any]\cr
+Arguments to \code{fun}. Best practice is to specify them in a \code{key = value} syntax.}
+
+\item{.args}{[\code{list}]\cr
+Arguments to \code{fun} as a (named) list. Will be passed after arguments in \code{...}.
+Default is \code{list()}.}
+}
+\value{
+Return value of \code{fun}.
+}
+\description{
+This function is supposed to be a replacement for \code{\link[base]{do.call}} in situations
+where you need to pass big R objects.
+Unlike \code{\link[base]{do.call}}, this function allows to pass objects via \code{...}
+to avoid a copy.
+}
+\examples{
+\dontrun{
+ library(microbenchmark)
+ x = 1:1e7
+ microbenchmark(do.call(head, list(x, n = 1)), do.call2("head", x, n = 1))
+}
+}
+
diff --git a/man/dropNamed.Rd b/man/dropNamed.Rd
new file mode 100644
index 0000000..160c551
--- /dev/null
+++ b/man/dropNamed.Rd
@@ -0,0 +1,26 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/dropNamed.R
+\name{dropNamed}
+\alias{dropNamed}
+\title{Drop named elements of an object.}
+\usage{
+dropNamed(x, drop = character(0L))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to drop named elements from.
+For a matrix or a data frames this function drops named columns via
+the second argument of the binary index operator \code{[,]}.
+Otherwise, the unary index operator \code{[]} is used for dropping.}
+
+\item{drop}{[\code{character}]\cr
+Names of elements to drop.}
+}
+\value{
+Subset of object of same type as \code{x}. The object is not simplified,
+ i.e, no dimensions are dropped as \code{[,,drop = FALSE]} is used.
+}
+\description{
+Drop named elements of an object.
+}
+
diff --git a/man/ensureVector.Rd b/man/ensureVector.Rd
new file mode 100644
index 0000000..376ea4b
--- /dev/null
+++ b/man/ensureVector.Rd
@@ -0,0 +1,31 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/ensureVector.R
+\name{ensureVector}
+\alias{ensureVector}
+\title{Blow up single scalars / objects to vectors / list by replication.}
+\usage{
+ensureVector(x, n, cl = NULL, names = NULL)
+}
+\arguments{
+\item{x}{[any]\cr
+Input element.}
+
+\item{n}{[\code{integer}]\cr
+Desired length.}
+
+\item{cl}{[\code{character(1)}*]\cr
+Only do the operation if \code{x} inherits from this class, otherwise simply let x pass.
+Default is \code{NULL} which means to always do the operation.}
+
+\item{names}{[\code{character}*] \cr
+Names for result.
+Default is \code{NULL}, which means no names.}
+}
+\value{
+Ether a vector or list of length \code{n} with replicated \code{x} or \code{x} unchanged..
+}
+\description{
+Useful for standard argument conversion where a user can input a single
+element, but this has to be replicated now n times for a resulting vector or list.
+}
+
diff --git a/man/explode.Rd b/man/explode.Rd
new file mode 100644
index 0000000..b888bfc
--- /dev/null
+++ b/man/explode.Rd
@@ -0,0 +1,28 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/explode.R
+\name{explode}
+\alias{explode}
+\title{Split up a string into substrings.}
+\usage{
+explode(x, sep = " ")
+}
+\arguments{
+\item{x}{[\code{character}]\cr
+Source string.}
+
+\item{sep}{[\code{character}]\cr
+Seperator whcih is used to split \code{x} into substrings.
+Default is \dQuote{ }.}
+}
+\value{
+[\code{vector}]
+ Vector of substrings.
+}
+\description{
+Split up a string into substrings according to a seperator.
+}
+\examples{
+explode("foo bar")
+explode("comma,seperated,values", sep = ",")
+}
+
diff --git a/man/extractSubList.Rd b/man/extractSubList.Rd
new file mode 100644
index 0000000..93f4744
--- /dev/null
+++ b/man/extractSubList.Rd
@@ -0,0 +1,46 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/extractSubList.R
+\name{extractSubList}
+\alias{extractSubList}
+\title{Extracts a named element from a list of lists.}
+\usage{
+extractSubList(xs, element, element.value, simplify = TRUE,
+ use.names = TRUE)
+}
+\arguments{
+\item{xs}{[\code{list}]\cr
+A list of named lists.}
+
+\item{element}{[\code{character}]\cr
+Name of element(s) to extract from the list elements of \code{xs}.
+What happens is this: \code{x$el1$el2....}.}
+
+\item{element.value}{[any]\cr
+If given, \code{\link{vapply}} is used and this argument is passed to \code{FUN.VALUE}.
+Note that even for repeated indexing (if length(element) > 1) you only
+pass one value here which refers to the data type of the final result.}
+
+\item{simplify}{[\code{logical(1)} | character(1)]\cr
+If \code{FALSE} \code{\link{lapply}} is used, otherwise \code{\link{sapply}}.
+If \dQuote{cols}, we expect the elements to be vectors of the same length and they are
+arranged as the columns of the resulting matrix.
+If \dQuote{rows}, likewise, but rows of the resulting matrix.
+Default is \code{TRUE}.}
+
+\item{use.names}{[\code{logical(1)}]\cr
+If \code{TRUE} and \code{xs} is named, the result is named as \code{xs},
+otherwise the result is unnamed.
+Default is \code{TRUE}.}
+}
+\value{
+[\code{list} | simplified \code{vector} | \code{matrix}]. See above.
+}
+\description{
+Extracts a named element from a list of lists.
+}
+\examples{
+xs = list(list(a = 1, b = 2), list(a = 5, b = 7))
+extractSubList(xs, "a")
+extractSubList(xs, "a", simplify = FALSE)
+}
+
diff --git a/man/filterNull.Rd b/man/filterNull.Rd
new file mode 100644
index 0000000..081b1c4
--- /dev/null
+++ b/man/filterNull.Rd
@@ -0,0 +1,19 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/filterNull.R
+\name{filterNull}
+\alias{filterNull}
+\title{Filter a list for NULL values}
+\usage{
+filterNull(li)
+}
+\arguments{
+\item{li}{[\code{list}]\cr
+List.}
+}
+\value{
+[\code{list}].
+}
+\description{
+Filter a list for NULL values
+}
+
diff --git a/man/getAttributeNames.Rd b/man/getAttributeNames.Rd
new file mode 100644
index 0000000..71f995b
--- /dev/null
+++ b/man/getAttributeNames.Rd
@@ -0,0 +1,22 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/getAttributeNames.R
+\name{getAttributeNames}
+\alias{getAttributeNames}
+\title{Helper function for determining the vector of attribute names
+of a given object.}
+\usage{
+getAttributeNames(obj)
+}
+\arguments{
+\item{obj}{[any]\cr
+Source object.}
+}
+\value{
+[\code{character}]
+ Vector of attribute names for the source object.
+}
+\description{
+Helper function for determining the vector of attribute names
+of a given object.
+}
+
diff --git a/man/getClass1.Rd b/man/getClass1.Rd
new file mode 100644
index 0000000..c529818
--- /dev/null
+++ b/man/getClass1.Rd
@@ -0,0 +1,22 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/getClass1.R
+\name{getClass1}
+\alias{getClass1}
+\title{Wrapper for \code{class(x)[1]}.}
+\usage{
+getClass1(x)
+}
+\arguments{
+\item{x}{[any]\cr
+Input object.}
+}
+\value{
+[\code{character(1)}].
+}
+\description{
+Wrapper for \code{class(x)[1]}.
+}
+\note{
+\code{getClass} is a function in \code{methods}. Do not confuse.
+}
+
diff --git a/man/getFirst.Rd b/man/getFirst.Rd
new file mode 100644
index 0000000..8b63048
--- /dev/null
+++ b/man/getFirst.Rd
@@ -0,0 +1,22 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/getFirstLast.R
+\name{getFirst}
+\alias{getFirst}
+\alias{getLast}
+\title{Get the first/last element of a list/vector.}
+\usage{
+getFirst(x)
+
+getLast(x)
+}
+\arguments{
+\item{x}{[\code{list} | \code{vector}]\cr
+The list or vector.}
+}
+\value{
+Selected element. The element name is dropped.
+}
+\description{
+Get the first/last element of a list/vector.
+}
+
diff --git a/man/getMaxIndex.Rd b/man/getMaxIndex.Rd
new file mode 100644
index 0000000..966a2d9
--- /dev/null
+++ b/man/getMaxIndex.Rd
@@ -0,0 +1,33 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/getMaxIndex.R
+\name{getMaxIndex}
+\alias{getMaxIndex}
+\alias{getMinIndex}
+\title{Return index of maximal/minimal element in numerical vector.}
+\usage{
+getMaxIndex(x, ties.method = "random", na.rm = FALSE)
+
+getMinIndex(x, ties.method = "random", na.rm = FALSE)
+}
+\arguments{
+\item{x}{[\code{numeric}]\cr
+Input vector.}
+
+\item{ties.method}{[\code{character(1)}]\cr
+How should ties be handled?
+Possible are: \dQuote{random}, \dQuote{first}, \dQuote{last}.
+Default is \dQuote{random}.}
+
+\item{na.rm}{[\code{logical(1)}]\cr
+If \code{FALSE}, NA is returned if an NA is encountered in \code{x}.
+If \code{TRUE}, NAs are disregarded.
+Default is \code{FALSE}}
+}
+\value{
+[\code{integer(1)}].
+}
+\description{
+If \code{x} is empty or only contains NAs which are to be removed,
+-1 is returned.
+}
+
diff --git a/man/getMaxIndexOfRows.Rd b/man/getMaxIndexOfRows.Rd
new file mode 100644
index 0000000..125f5e2
--- /dev/null
+++ b/man/getMaxIndexOfRows.Rd
@@ -0,0 +1,49 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/getMaxColIndex.R
+\name{getMaxIndexOfRows}
+\alias{getMaxIndexOfCols}
+\alias{getMaxIndexOfRows}
+\alias{getMinIndexOfCols}
+\alias{getMinIndexOfRows}
+\title{Find row- or columnwise the index of the maximal / minimal element in a matrix.}
+\usage{
+getMaxIndexOfRows(x, ties.method = "random", na.rm = FALSE)
+
+getMinIndexOfRows(x, ties.method = "random", na.rm = FALSE)
+
+getMaxIndexOfCols(x, ties.method = "random", na.rm = FALSE)
+
+getMinIndexOfCols(x, ties.method = "random", na.rm = FALSE)
+}
+\arguments{
+\item{x}{[\code{matrix(n,m)}] \cr
+Numerical input matrix.}
+
+\item{ties.method}{[\code{character(1)}]\cr
+How should ties be handled?
+Possible are: \dQuote{random}, \dQuote{first}, \dQuote{last}.
+Default is \dQuote{random}.}
+
+\item{na.rm}{[\code{logical(1)}]\cr
+If \code{FALSE}, NA is returned if an NA is encountered in \code{x}.
+If \code{TRUE}, NAs are disregarded.
+Default is \code{FALSE}}
+}
+\value{
+[\code{integer(n)}].
+}
+\description{
+\code{getMaxIndexOfRows} returns the index of the maximal element of each row.
+\code{getMinIndexOfRows} returns the index of the minimal element of each row.
+\code{getMaxIndexOfCols} returns the index of the maximal element of each col.
+\code{getMinIndexOfCols} returns the index of the minimal element of each col.
+If a corresponding vector (row or col) is empty, possibly after NA removal, -1 is returned
+as index.
+}
+\examples{
+x = matrix(runif(5 * 3), ncol = 3)
+print(x)
+print(getMaxIndexOfRows(x))
+print(getMinIndexOfRows(x))
+}
+
diff --git a/man/getOperatingSystem.Rd b/man/getOperatingSystem.Rd
new file mode 100644
index 0000000..c4d1355
--- /dev/null
+++ b/man/getOperatingSystem.Rd
@@ -0,0 +1,33 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/getOperatingSystem.R
+\name{getOperatingSystem}
+\alias{getOperatingSystem}
+\alias{isDarwin}
+\alias{isLinux}
+\alias{isUnix}
+\alias{isWindows}
+\title{Functions to determine the operating system.}
+\usage{
+getOperatingSystem()
+
+isWindows()
+
+isUnix()
+
+isLinux()
+
+isDarwin()
+}
+\value{
+See above.
+}
+\description{
+\itemize{
+\item{getOperatingSystem}{Simple wrapper for \code{.Platform$OS.type}, returns \code{character(1)}.}
+\item{isUnix}{Predicate for OS string, returns \code{logical(1)}. Currently this would include Unix, Linux and Mac flavours.}
+\item{isLinux}{Predicate for sysname string, returns \code{logical(1)}.}
+\item{isDarwin}{Predicate for sysname string, returns \code{logical(1)}.}
+\item{isWindows}{Predicate for OS string, returns \code{logical(1)}.}
+}
+}
+
diff --git a/man/getRelativePath.Rd b/man/getRelativePath.Rd
new file mode 100644
index 0000000..6ece36e
--- /dev/null
+++ b/man/getRelativePath.Rd
@@ -0,0 +1,29 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/getRelativePath.R
+\name{getRelativePath}
+\alias{getRelativePath}
+\title{Construct a path relative to another}
+\usage{
+getRelativePath(to, from = getwd(), ignore.case = isWindows())
+}
+\arguments{
+\item{to}{[\code{character(1)}]\cr
+Where the relative path should point to.}
+
+\item{from}{[\code{character(1)}]\cr
+From which part to start.
+Default is \code{\link[base]{getwd}}.}
+
+\item{ignore.case}{[\code{logical(1)}]\cr
+Should path comparisons be made case insensitve?
+Default is \code{TRUE} on Windows systems and \code{FALSE} on other systems.}
+}
+\value{
+[character(1)]: A relative path.
+}
+\description{
+Constructs a relative path from path \code{from} to path \code{to}.
+If this is not possible (i.e. different drive letters on windows systems),
+\code{NA} is returned.
+}
+
diff --git a/man/getUnixTime.Rd b/man/getUnixTime.Rd
new file mode 100644
index 0000000..2245f42
--- /dev/null
+++ b/man/getUnixTime.Rd
@@ -0,0 +1,15 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/getUnixTime.R
+\name{getUnixTime}
+\alias{getUnixTime}
+\title{Current time in seconds.}
+\usage{
+getUnixTime()
+}
+\value{
+[\code{integer(1)}].
+}
+\description{
+Simple wrapper for \code{as.integer(Sys.time())}.
+}
+
diff --git a/man/getUsedFactorLevels.Rd b/man/getUsedFactorLevels.Rd
new file mode 100644
index 0000000..eb30df6
--- /dev/null
+++ b/man/getUsedFactorLevels.Rd
@@ -0,0 +1,20 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/getUsedFactorLevels.R
+\name{getUsedFactorLevels}
+\alias{getUsedFactorLevels}
+\title{Determines used factor levels.}
+\usage{
+getUsedFactorLevels(x)
+}
+\arguments{
+\item{x}{[\code{factor}]\cr
+The factor.}
+}
+\value{
+[\code{character}]
+}
+\description{
+Determines the factor levels of a factor type vector
+that are actually occuring in it.
+}
+
diff --git a/man/hasAttributes.Rd b/man/hasAttributes.Rd
new file mode 100644
index 0000000..11a8806
--- /dev/null
+++ b/man/hasAttributes.Rd
@@ -0,0 +1,24 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/hasAttributes.R
+\name{hasAttributes}
+\alias{hasAttributes}
+\title{Check if given object has certain attributes.}
+\usage{
+hasAttributes(obj, attribute.names)
+}
+\arguments{
+\item{obj}{[mixed]\cr
+Arbitrary R object.}
+
+\item{attribute.names}{[\code{character}]\cr
+Vector of strings, i.e., attribute names.}
+}
+\value{
+[\code{logical(1)}]
+ \code{TRUE} if object \code{x} contains all attributes from \code{attributeNames}
+ and \code{FALSE} otherwise.
+}
+\description{
+Check if given object has certain attributes.
+}
+
diff --git a/man/insert.Rd b/man/insert.Rd
new file mode 100644
index 0000000..998242f
--- /dev/null
+++ b/man/insert.Rd
@@ -0,0 +1,33 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/insert.R
+\name{insert}
+\alias{insert}
+\title{Insert elements from one list/vector into another list/vector.}
+\usage{
+insert(xs1, xs2, elements)
+}
+\arguments{
+\item{xs1}{[\code{list}]\cr
+First list/vector.}
+
+\item{xs2}{[\code{list}]\cr
+Second vector/list. Must be fully and uniquely named.}
+
+\item{elements}{[\code{character}]\cr
+Elements from \code{xs2} to insert into \code{xs1}.
+Default is all.}
+}
+\value{
+\code{x1} with replaced elements from \code{x2}.
+}
+\description{
+Inserts elements from \code{xs2} into \code{xs1} by name,
+overwriting elements of equal names.
+}
+\examples{
+xs1 = list(a = 1, b = 2)
+xs2 = list(b = 1, c = 4)
+insert(xs1, xs2)
+insert(xs1, xs2, elements = "c")
+}
+
diff --git a/man/is.error.Rd b/man/is.error.Rd
new file mode 100644
index 0000000..58bee09
--- /dev/null
+++ b/man/is.error.Rd
@@ -0,0 +1,28 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/is_error.R
+\name{is.error}
+\alias{is.error}
+\title{Is return value of try an exception?}
+\usage{
+is.error(x)
+}
+\arguments{
+\item{x}{[any]\cr
+ Any object, usually the return value of \code{\link[base]{try}},
+\code{\link[base]{tryCatch}}, or a function which may return a
+\code{\link[base]{simpleError}}.}
+}
+\value{
+[\code{logical(1)}].
+}
+\description{
+Checks if an object is of class \dQuote{try-error} or
+\dQuote{error}.
+}
+\examples{
+x = try(stop("foo"))
+print(is.error(x))
+x = 1
+print(is.error(x))
+}
+
diff --git a/man/isDirectory.Rd b/man/isDirectory.Rd
new file mode 100644
index 0000000..3ebe342
--- /dev/null
+++ b/man/isDirectory.Rd
@@ -0,0 +1,23 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/directory.R
+\name{isDirectory}
+\alias{isDirectory}
+\title{Is one / are several files a directory?}
+\usage{
+isDirectory(...)
+}
+\arguments{
+\item{...}{[\code{character(1)}]\cr
+File names, all strings.}
+}
+\value{
+[\code{logical}].
+}
+\description{
+If a file does not exist, \code{FALSE} is returned.
+}
+\examples{
+print(isDirectory(tempdir()))
+print(isDirectory(tempfile()))
+}
+
diff --git a/man/isEmptyDirectory.Rd b/man/isEmptyDirectory.Rd
new file mode 100644
index 0000000..6421e29
--- /dev/null
+++ b/man/isEmptyDirectory.Rd
@@ -0,0 +1,23 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/directory.R
+\name{isEmptyDirectory}
+\alias{isEmptyDirectory}
+\title{Is one / are several directories empty?}
+\usage{
+isEmptyDirectory(...)
+}
+\arguments{
+\item{...}{[\code{character(1)}]\cr
+Directory names, all strings.}
+}
+\value{
+[\code{logical}].
+}
+\description{
+If file does not exist or is not a directory, \code{FALSE} is returned.
+}
+\examples{
+print(isEmptyDirectory(tempdir()))
+print(isEmptyDirectory(tempfile()))
+}
+
diff --git a/man/isExpensiveExampleOk.Rd b/man/isExpensiveExampleOk.Rd
new file mode 100644
index 0000000..e696a16
--- /dev/null
+++ b/man/isExpensiveExampleOk.Rd
@@ -0,0 +1,27 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/isExpensiveExampleOk.R
+\name{isExpensiveExampleOk}
+\alias{isExpensiveExampleOk}
+\title{Conditional checking for expensive examples.}
+\usage{
+isExpensiveExampleOk()
+}
+\value{
+[\code{logical(1)}].
+}
+\description{
+Queries environment variable \dQuote{R_EXPENSIVE_EXAMPLE_OK}.
+Returns \code{TRUE} iff set exactly to \dQuote{TRUE}.
+This allows conditional checking of expensive examples in packages
+via R CMD CHECK, so they are not run on CRAN, but at least
+on your local computer.
+A better option than \dQuote{dont_run} in many cases, where such examples
+are not checked at all.
+}
+\examples{
+# extremely costly random number generation, that we dont want checked on CRAN
+if (isExpensiveExampleOk()) {
+ runif(1)
+}
+}
+
diff --git a/man/isFALSE.Rd b/man/isFALSE.Rd
new file mode 100644
index 0000000..6072046
--- /dev/null
+++ b/man/isFALSE.Rd
@@ -0,0 +1,23 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/isFALSE.R
+\name{isFALSE}
+\alias{isFALSE}
+\title{A wrapper for \code{identical(x, FALSE)}.}
+\usage{
+isFALSE(x)
+}
+\arguments{
+\item{x}{[any]\cr
+Your object.}
+}
+\value{
+[\code{logical(1)}].
+}
+\description{
+A wrapper for \code{identical(x, FALSE)}.
+}
+\examples{
+isFALSE(0)
+isFALSE(FALSE)
+}
+
diff --git a/man/isProperlyNamed.Rd b/man/isProperlyNamed.Rd
new file mode 100644
index 0000000..aed1eac
--- /dev/null
+++ b/man/isProperlyNamed.Rd
@@ -0,0 +1,24 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/isProperlyNamed.R
+\name{isProperlyNamed}
+\alias{isProperlyNamed}
+\title{Are all elements of a list / vector uniquely named?}
+\usage{
+isProperlyNamed(x)
+}
+\arguments{
+\item{x}{[\code{vector}]\cr
+The vector or list.}
+}
+\value{
+[\code{logical(1)}].
+}
+\description{
+\code{NA} or \dQuote{} are not allowed as names.
+}
+\examples{
+isProperlyNamed(list(1))
+isProperlyNamed(list(a = 1))
+isProperlyNamed(list(a = 1, 2))
+}
+
diff --git a/man/isScalarNA.Rd b/man/isScalarNA.Rd
new file mode 100644
index 0000000..0d621cf
--- /dev/null
+++ b/man/isScalarNA.Rd
@@ -0,0 +1,19 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/isScalarNA.R
+\name{isScalarNA}
+\alias{isScalarNA}
+\title{Checks whether an object is a scalar NA value.}
+\usage{
+isScalarNA(x)
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+}
+\value{
+[\code{logical(1)}].
+}
+\description{
+Checks whether object is from \code{(NA, NA_integer, NA_real_, NA_character_, NA_complex_)}.
+}
+
diff --git a/man/isScalarValue.Rd b/man/isScalarValue.Rd
new file mode 100644
index 0000000..bfc9b10
--- /dev/null
+++ b/man/isScalarValue.Rd
@@ -0,0 +1,50 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/isScalarValue.R
+\name{isScalarValue}
+\alias{isScalarCharacter}
+\alias{isScalarComplex}
+\alias{isScalarFactor}
+\alias{isScalarInteger}
+\alias{isScalarLogical}
+\alias{isScalarNumeric}
+\alias{isScalarValue}
+\title{Is given argument an atomic vector or factor of length 1?}
+\usage{
+isScalarValue(x, na.ok = TRUE, null.ok = FALSE, type = "atomic")
+
+isScalarLogical(x, na.ok = TRUE, null.ok = FALSE)
+
+isScalarNumeric(x, na.ok = TRUE, null.ok = FALSE)
+
+isScalarInteger(x, na.ok = TRUE, null.ok = FALSE)
+
+isScalarComplex(x, na.ok = TRUE, null.ok = FALSE)
+
+isScalarCharacter(x, na.ok = TRUE, null.ok = FALSE)
+
+isScalarFactor(x, na.ok = TRUE, null.ok = FALSE)
+}
+\arguments{
+\item{x}{[any]\cr
+Argument.}
+
+\item{na.ok}{[\code{logical(1)}]\cr
+Is \code{NA} considered a scalar?
+Default is \code{TRUE}.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+Is \code{NULL} considered a scalar?
+Default is \code{FALSE}.}
+
+\item{type}{[\code{character(1)}]\cr
+Allows to restrict to specific type, e.g., \dQuote{numeric}?
+But instead of this argument you might want to consider using \code{isScalar<Type>}.
+Default is \dQuote{atomic}, so no special restriction.}
+}
+\value{
+[\code{logical(1)}].
+}
+\description{
+More specific functions for scalars of a given type exist, too.
+}
+
diff --git a/man/isSubset.Rd b/man/isSubset.Rd
new file mode 100644
index 0000000..1713c46
--- /dev/null
+++ b/man/isSubset.Rd
@@ -0,0 +1,27 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/isSubset.R
+\name{isSubset}
+\alias{isSubset}
+\title{Check subset relation on two vectors.}
+\usage{
+isSubset(x, y, strict = FALSE)
+}
+\arguments{
+\item{x}{[\code{vector}]\cr
+Source vector.}
+
+\item{y}{[\code{vector}]\cr
+Vector of the same mode as \code{x}.}
+
+\item{strict}{[\code{logical(1)}]\cr
+Checks for strict/proper subset relation.}
+}
+\value{
+[\code{logical(1)}]
+ \code{TRUE} if each element of \code{x} is also contained in \code{y}, i. e.,
+ if \code{x} is a subset of \code{y} and \code{FALSE} otherwise.
+}
+\description{
+Check subset relation on two vectors.
+}
+
diff --git a/man/isSuperset.Rd b/man/isSuperset.Rd
new file mode 100644
index 0000000..257f445
--- /dev/null
+++ b/man/isSuperset.Rd
@@ -0,0 +1,27 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/isSuperset.R
+\name{isSuperset}
+\alias{isSuperset}
+\title{Check superset relation on two vectors.}
+\usage{
+isSuperset(x, y, strict = FALSE)
+}
+\arguments{
+\item{x}{[\code{vector}]\cr
+Source vector.}
+
+\item{y}{[\code{vector}]\cr
+Vector of the same mode as \code{x}.}
+
+\item{strict}{[\code{logical(1)}]\cr
+Checks for strict/proper superset relation.}
+}
+\value{
+[\code{logical(1)}]
+ \code{TRUE} if each element of \code{y} is also contained in \code{x}, i. e.,
+ if \code{y} is a subset of \code{x} and \code{FALSE} otherwise.
+}
+\description{
+Check superset relation on two vectors.
+}
+
diff --git a/man/isValidName.Rd b/man/isValidName.Rd
new file mode 100644
index 0000000..d0cb123
--- /dev/null
+++ b/man/isValidName.Rd
@@ -0,0 +1,25 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/isValidName.R
+\name{isValidName}
+\alias{isValidName}
+\title{Can some strings be used for column or list element names without problems?}
+\usage{
+isValidName(x, unique = TRUE)
+}
+\arguments{
+\item{x}{[\code{character}]\cr
+Character vector to check.}
+
+\item{unique}{[\code{logical(1)}]\cr
+Should the names be unique?
+Default is \code{TRUE}.}
+}
+\value{
+[\code{logical}]. One Boolean entry for each string in \code{x}.
+ If the entries are not unique and \code{unique} is enabled, the first duplicate will
+ be \code{FALSE}.
+}
+\description{
+Can some strings be used for column or list element names without problems?
+}
+
diff --git a/man/itostr.Rd b/man/itostr.Rd
new file mode 100644
index 0000000..dda8d88
--- /dev/null
+++ b/man/itostr.Rd
@@ -0,0 +1,31 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/itostr.R
+\name{itostr}
+\alias{itostr}
+\title{Convert Integers to Strings}
+\usage{
+itostr(x, base = 10L)
+}
+\arguments{
+\item{x}{[\code{integer}]\cr
+Vector of integers to convert.}
+
+\item{base}{[\code{integer(1)}]\cr
+Base for conversion. Values between 2 and 36 (inclusive) are allowed.}
+}
+\value{
+\code{character(length(x))}.
+}
+\description{
+This is the counterpart of \code{\link[base]{strtoi}}.
+For a base greater than \sQuote{10}, letters \sQuote{a} to \sQuote{z}
+are used to represent \sQuote{10} to \sQuote{35}.
+}
+\examples{
+# binary representation of the first 10 natural numbers
+itostr(1:10, 2)
+
+# base36 encoding of a large number
+itostr(1e7, 36)
+}
+
diff --git a/man/lib.Rd b/man/lib.Rd
new file mode 100644
index 0000000..008dadd
--- /dev/null
+++ b/man/lib.Rd
@@ -0,0 +1,27 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/lib.R
+\name{lib}
+\alias{lib}
+\title{A wrapper for \code{library}.}
+\usage{
+lib(...)
+}
+\arguments{
+\item{...}{[any]\cr
+Package names.}
+}
+\value{
+[\code{logical}]: Named logical vector determining the success
+ of package load.
+}
+\description{
+Tries to load packages. If the packages are not found, they will be installed from
+the default repository. This function is intended for use in interactive sessions
+and should not be used by other packages.
+}
+\examples{
+\dontrun{
+lib("BBmisc", "MASS", "rpart")
+}
+}
+
diff --git a/man/load2.Rd b/man/load2.Rd
new file mode 100644
index 0000000..b742f3e
--- /dev/null
+++ b/man/load2.Rd
@@ -0,0 +1,42 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/load2.R
+\name{load2}
+\alias{load2}
+\title{Load RData file and return objects in it.}
+\usage{
+load2(file, parts, simplify = TRUE, envir, impute)
+}
+\arguments{
+\item{file}{[\code{character(1)}]\cr
+File to load.}
+
+\item{parts}{[\code{character}]\cr
+Elements in file to load.
+Default is all.}
+
+\item{simplify}{[\code{logical(1)}]\cr
+If \code{TRUE}, a list is only returned if \code{parts} and the file contain both more
+than 1 element, otherwise the element is directly returned.
+Default is \code{TRUE}.}
+
+\item{envir}{[\code{environment(1)}]\cr
+Assign objects to this environment.
+Default is not to assign.}
+
+\item{impute}{[\code{ANY}]\cr
+If \code{file} does not exists, return \code{impute} instead.
+Default is missing which will result in an exception if \code{file} is not found.}
+}
+\value{
+Either a single object or a list.
+}
+\description{
+Load RData file and return objects in it.
+}
+\examples{
+fn = tempfile()
+save2(file = fn, a = 1, b = 2, c = 3)
+load2(fn, parts = "a")
+load2(fn, parts = c("a", "c"))
+}
+
diff --git a/man/lsort.Rd b/man/lsort.Rd
new file mode 100644
index 0000000..efefd0c
--- /dev/null
+++ b/man/lsort.Rd
@@ -0,0 +1,18 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/lsort.R
+\name{lsort}
+\alias{lsort}
+\title{A wrapper for \code{\link{sort}} to sort using the \dQuote{C} collating rules.}
+\usage{
+lsort(...)
+}
+\arguments{
+\item{...}{Options passed to sort.}
+}
+\value{
+See \code{\link{sort}}.
+}
+\description{
+A wrapper for \code{\link{sort}} to sort using the \dQuote{C} collating rules.
+}
+
diff --git a/man/makeDataFrame.Rd b/man/makeDataFrame.Rd
new file mode 100644
index 0000000..deda129
--- /dev/null
+++ b/man/makeDataFrame.Rd
@@ -0,0 +1,43 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/makeDataFrame.R
+\name{makeDataFrame}
+\alias{makeDataFrame}
+\title{Initialize data.frame in a convenient way.}
+\usage{
+makeDataFrame(nrow, ncol, col.types, init, row.names = NULL,
+ col.names = sprintf("V\%i", seq_len(ncol)))
+}
+\arguments{
+\item{nrow}{[\code{integer(1)}]\cr
+Nubmer of rows.}
+
+\item{ncol}{[\code{integer(1)}]\cr
+Number of columns.}
+
+\item{col.types}{[\code{character(ncol)} | \code{character(1)}]\cr
+Data types of columns.
+If you only pass one type, it will be replicated.
+Supported are all atomic modes also supported by
+\code{\link[base]{vector}}, i.e. all common data frame types except factors.}
+
+\item{init}{[any]\cr
+Scalar object to initialize all elements of the data.frame.
+You do not need to specify \code{col.types} if you pass this.}
+
+\item{row.names}{[\code{character} | \code{integer} | \code{NULL}]\cr
+Row names.
+Default is \code{NULL}.}
+
+\item{col.names}{[\code{character} | \code{integer}]\cr
+Column names.
+Default is \dQuote{V1}, \dQuote{V2}, and so on.}
+}
+\description{
+Initialize data.frame in a convenient way.
+}
+\examples{
+print(makeDataFrame(3, 2, init = 7))
+print(makeDataFrame(3, 2, "logical"))
+print(makeDataFrame(3, 2, c("logical", "numeric")))
+}
+
diff --git a/man/makeFileCache.Rd b/man/makeFileCache.Rd
new file mode 100644
index 0000000..55c8b12
--- /dev/null
+++ b/man/makeFileCache.Rd
@@ -0,0 +1,24 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/FileCache.R
+\name{makeFileCache}
+\alias{makeFileCache}
+\title{A caching wrapper around load2.}
+\usage{
+makeFileCache(use.cache = TRUE)
+}
+\arguments{
+\item{use.cache}{[\code{logical(1)}]\cr
+Enable the cache?
+Default is \code{TRUE}.}
+}
+\value{
+[\code{function()}] with argument \code{slot}
+ (name of the slot to cache the object in, default is \dQuote{default}).
+ All other arguments are passed down to \code{\link{load2}}.
+}
+\description{
+This closure returns a wrapper around \code{\link{load2}} which per
+default caches loaded objects and returns the cached version
+in subsequent calls.
+}
+
diff --git a/man/makeProgressBar.Rd b/man/makeProgressBar.Rd
new file mode 100644
index 0000000..bbc4028
--- /dev/null
+++ b/man/makeProgressBar.Rd
@@ -0,0 +1,91 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/makeProgressBar.R
+\name{makeProgressBar}
+\alias{ProgressBar}
+\alias{makeProgressBar}
+\title{Create a progress bar with estimated time.}
+\usage{
+makeProgressBar(min = 0, max = 100, label = "", char = "+",
+ style = getOption("BBmisc.ProgressBar.style", "text"),
+ width = getOption("BBmisc.ProgressBar.width", getOption("width")),
+ stream = getOption("BBmisc.ProgressBar.stream", "stderr"))
+}
+\arguments{
+\item{min}{[\code{numeric(1)}]\cr
+Minimum value, default is 0.}
+
+\item{max}{[\code{numeric(1)}]\cr
+Maximum value, default is 100.}
+
+\item{label}{[\code{character(1)}]\cr
+Label shown in front of the progress bar.
+Note that if you later set \code{msg} in the progress bar function,
+the message will be left-padded to the length of this label, therefore
+it should be at least as long as the longest message you want to display.
+Default is \dQuote{}.}
+
+\item{char}{[\code{character(1)}]\cr
+A single character used to display progress in the bar.
+Default is \sQuote{+}.}
+
+\item{style}{[\code{character(1)}]\cr
+Style of the progress bar. Default is set via options (see details).}
+
+\item{width}{[\code{integer(1)}]\cr
+Width of the progress bar. Default is set via options (see details).}
+
+\item{stream}{[\code{character(1)}]\cr
+Stream to use. Default is set via options (see details).}
+}
+\value{
+[\code{\link{ProgressBar}}]. A list with following functions:
+ \item{set [\code{function(value, msg = label)}]}{Set the bar to a value and possibly display a message instead of the label.}
+ \item{inc [\code{function(value, msg = label)}]}{Increase the bar and possibly display a message instead of the label.}
+ \item{kill [\code{function(clear = FALSE)}]}{Kill the bar so it cannot be used anymore. Cursor is moved to new line. You can also erase its display.}
+ \item{error [\code{function(e)}]}{Useful in \code{tryCatch} to properly display error messages below the bar. See the example.}
+}
+\description{
+Create a progress bar function that displays the estimated time till
+completion and optional messages. Call the returned functions \code{set} or
+\code{inc} during a loop to change the display.
+Note that you are not allowed to decrease the value of the bar.
+If you call these function without setting any of the arguments
+the bar is simply redrawn with the current value.
+For errorhandling use \code{error} and have a look at the example below.
+
+You can globally change the behavior of all bars by setting the option
+\code{options(BBmisc.ProgressBar.style)} either to \dQuote{text} (the default)
+or \dQuote{off}, which display no bars at all.
+
+You can globally change the width of all bars by setting the option
+\code{options(BBmisc.ProgressBar.width)}. By default this is \code{getOption("width")}.
+
+You can globally set the stream where the output of the bar is directed by setting the option
+\code{options(BBmisc.ProgressBar.stream)} either to \dQuote{stderr} (the default)
+or \dQuote{stdout}. Note that using the latter will result in the bar being shown in
+reports generated by Sweave or knitr, what you probably do not want.
+}
+\examples{
+bar = makeProgressBar(max = 5, label = "test-bar")
+for (i in 0:5) {
+ bar$set(i)
+ Sys.sleep(0.2)
+}
+bar = makeProgressBar(max = 5, label = "test-bar")
+for (i in 1:5) {
+ bar$inc(1)
+ Sys.sleep(0.2)
+}
+# display errors properly (in next line)
+\dontrun{
+f = function(i) if (i>2) stop("foo")
+bar = makeProgressBar(max = 5, label = "test-bar")
+for (i in 1:5) {
+ tryCatch ({
+ f(i)
+ bar$set(i)
+ }, error = bar$error)
+}
+}
+}
+
diff --git a/man/makeS3Obj.Rd b/man/makeS3Obj.Rd
new file mode 100644
index 0000000..d8ce7c9
--- /dev/null
+++ b/man/makeS3Obj.Rd
@@ -0,0 +1,25 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/makeS3Obj.R
+\name{makeS3Obj}
+\alias{makeS3Obj}
+\title{Simple constructor for S3 objects based on lists.}
+\usage{
+makeS3Obj(classes, ...)
+}
+\arguments{
+\item{classes}{[\code{character}]\cr
+Class(es) for constructed object.}
+
+\item{...}{[any]\cr
+Key-value pairs for class members.}
+}
+\value{
+Object.
+}
+\description{
+Simple wrapper for \code{as.list} and \code{\link{setClasses}}.
+}
+\examples{
+makeS3Obj("car", speed = 100, color = "red")
+}
+
diff --git a/man/makeSimpleFileLogger.Rd b/man/makeSimpleFileLogger.Rd
new file mode 100644
index 0000000..978e402
--- /dev/null
+++ b/man/makeSimpleFileLogger.Rd
@@ -0,0 +1,34 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/makeSimpleFileLogger.R
+\name{makeSimpleFileLogger}
+\alias{SimpleFileLogger}
+\alias{makeSimpleFileLogger}
+\title{Simple logger which outputs to a file.}
+\usage{
+makeSimpleFileLogger(logfile, touch = FALSE, keep = 10L)
+}
+\arguments{
+\item{logfile}{[\code{character(1)}]\cr
+File to log to.}
+
+\item{touch}{[\code{logical(1)}]\cr
+Should the file be created before the first log message?
+Default is \code{FALSE}.}
+
+\item{keep}{[\code{integer(1)}]\cr
+Number of log messages to keep in memory for quick access.
+Default is \code{10}.}
+}
+\value{
+[\code{\link{SimpleFileLogger}}]. A list with following functions:
+ \item{log [\code{function(msg)}]}{Send log message.}
+ \item{getMessages [\code{function(n)}]}{Get last \code{n} log messages.}
+ \item{clear [\code{function()}]}{Resets logger and deletes log file.}
+ \item{getSize [\code{function()}]}{Returns the number of logs written.}
+ \item{getLogfile [\code{function()}]}{Returns the full file name logs are written to.}
+}
+\description{
+Creates a simple file logger closure to log to a file, including time stamps.
+An optional buffer holds the last few log messages.
+}
+
diff --git a/man/mapValues.Rd b/man/mapValues.Rd
new file mode 100644
index 0000000..c88dcef
--- /dev/null
+++ b/man/mapValues.Rd
@@ -0,0 +1,52 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/mapValues.R
+\name{mapValues}
+\alias{mapValues}
+\title{Replace values in atomic vectors}
+\usage{
+mapValues(x, from, to, regex = FALSE, ignore.case = FALSE, perl = FALSE,
+ fixed = FALSE)
+}
+\arguments{
+\item{x}{[\code{atomic}]\cr
+Atomic vector. If \code{x} is a factor, all replacements work on the levels.}
+
+\item{from}{[\code{atomic}]\cr
+Atomic vector with values to replace, same length as \code{to}.}
+
+\item{to}{[\code{atomic}]\cr
+Atomic vector with replacements, same length as \code{from}.}
+
+\item{regex}{[\code{logical}]\cr
+Use regular expression matching? Default is \code{FALSE}.}
+
+\item{ignore.case}{[\code{logical}]\cr
+Argument passed to \code{\link[base]{gsub}}.}
+
+\item{perl}{[\code{logical}]\cr
+Argument passed to \code{\link[base]{gsub}}.}
+
+\item{fixed}{[\code{logical}]\cr
+Argument passed to \code{\link[base]{gsub}}.}
+}
+\value{
+[\code{atomic}].
+}
+\description{
+Replace values in atomic vectors
+}
+\details{
+Replaces values specified in \code{from} with values in \code{to}.
+Regular expression matching can be enabled which calls \code{\link[base]{gsub}} iteratively
+on \code{x} to replace all patterns in \code{from} with replacements in \code{to}.
+}
+\examples{
+# replace integers
+x = 1:5
+mapValues(x, c(2, 3), c(99, 100))
+
+# replace factor levels using regex matching
+x = factor(c("aab", "aba", "baa"))
+mapValues(x, "a.a", "zzz", regex = TRUE)
+}
+
diff --git a/man/messagef.Rd b/man/messagef.Rd
new file mode 100644
index 0000000..95979bb
--- /dev/null
+++ b/man/messagef.Rd
@@ -0,0 +1,26 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/messagef.R
+\name{messagef}
+\alias{messagef}
+\title{Wrapper for message and sprintf.}
+\usage{
+messagef(..., .newline = TRUE)
+}
+\arguments{
+\item{...}{[any]\cr
+See \code{\link{sprintf}}.}
+
+\item{.newline}{[logical(1)]\cr
+Add a newline to the message. Default is \code{TRUE}.}
+}
+\value{
+Nothing.
+}
+\description{
+A simple wrapper for \code{message(sprintf(...))}.
+}
+\examples{
+msg = "a message"
+warningf("this is \%s", msg)
+}
+
diff --git a/man/namedList.Rd b/man/namedList.Rd
new file mode 100644
index 0000000..4446569
--- /dev/null
+++ b/man/namedList.Rd
@@ -0,0 +1,27 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/namedList.R
+\name{namedList}
+\alias{namedList}
+\title{Create named list, possibly initialized with a certain element.}
+\usage{
+namedList(names, init)
+}
+\arguments{
+\item{names}{[\code{character}]\cr
+Names of elements.}
+
+\item{init}{[valid R expression]\cr
+If given all list elements are initialized to this, otherwise
+\code{NULL} is used.}
+}
+\value{
+[\code{list}].
+}
+\description{
+Create named list, possibly initialized with a certain element.
+}
+\examples{
+namedList(c("a", "b"))
+namedList(c("a", "b"), init = 1)
+}
+
diff --git a/man/names2.Rd b/man/names2.Rd
new file mode 100644
index 0000000..20e55ec
--- /dev/null
+++ b/man/names2.Rd
@@ -0,0 +1,33 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/names2.R
+\name{names2}
+\alias{names2}
+\title{Replacement for names which always returns a vector.}
+\usage{
+names2(x, missing.val = NA_character_)
+}
+\arguments{
+\item{x}{[\code{ANY}]\cr
+Object, probably named.}
+
+\item{missing.val}{[\code{ANY}]\cr
+Value to set for missing names. Default is \code{NA_character_}.}
+}
+\value{
+[\code{character}]: vector of the same length as \code{x}.
+}
+\description{
+A simple wrapper for \code{\link[base]{names}}.
+Returns a vector even if no names attribute is set.
+Values \code{NA} and \code{""} are treated as missing and
+replaced with the value provided in \code{missing.val}.
+}
+\examples{
+x = 1:3
+names(x)
+names2(x)
+names(x[1:2]) = letters[1:2]
+names(x)
+names2(x)
+}
+
diff --git a/man/nin.Rd b/man/nin.Rd
new file mode 100644
index 0000000..194a363
--- /dev/null
+++ b/man/nin.Rd
@@ -0,0 +1,19 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/nin.R
+\name{\%nin\%}
+\alias{\%nin\%}
+\title{Simply a negated \code{in} operator.}
+\usage{
+x \%nin\% y
+}
+\arguments{
+\item{x}{[\code{vector}]\cr
+Values that should not be in \code{y}.}
+
+\item{y}{[\code{vector}]\cr
+Values to match against.}
+}
+\description{
+Simply a negated \code{in} operator.
+}
+
diff --git a/man/normalize.Rd b/man/normalize.Rd
new file mode 100644
index 0000000..cab4e3c
--- /dev/null
+++ b/man/normalize.Rd
@@ -0,0 +1,58 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/normalize.R
+\name{normalize}
+\alias{normalize}
+\title{Normalizes numeric data to a given scale.}
+\usage{
+normalize(x, method = "standardize", range = c(0, 1), margin = 1L,
+ on.constant = "quiet")
+}
+\arguments{
+\item{x}{[\code{numeric} | \code{matrix} | \code{data.frame}]\cr
+Input vector.}
+
+\item{method}{[\code{character(1)}]\cr
+Normalizing method. Available are:\cr
+\dQuote{center}: Subtract mean.\cr
+\dQuote{scale}: Divide by standard deviation.\cr
+\dQuote{standardize}: Center and scale.\cr
+\dQuote{range}: Scale to a given range.\cr}
+
+\item{range}{[\code{numeric(2)}]\cr
+Range for method \dQuote{range}.
+The first value represents the replacement for the min value, the second is the substitute for the max value.
+So it is possible to reverse the order by giving \code{range = c(1,0)}.
+Default is \code{c(0,1)}.}
+
+\item{margin}{[\code{integer(1)}]\cr
+1 = rows, 2 = cols.
+Same is in \code{\link{apply}}
+Default is 1.}
+
+\item{on.constant}{[\code{character(1)}]\cr
+How should constant vectors be treated? Only used, of \dQuote{method != center},
+since this methods does not fail for constant vectors. Possible actions are:\cr
+\dQuote{quiet}: Depending on the method, treat them quietly:\cr
+ \dQuote{scale}: No division by standard deviation is done, input values.
+ will be returned untouched.\cr
+ \dQuote{standardize}: Only the mean is subtracted, no division is done.\cr
+ \dQuote{range}: All values are mapped to the mean of the given range.\cr
+\dQuote{warn}: Same behaviour as \dQuote{quiet}, but print a warning message.\cr
+\dQuote{stop}: Stop with an error.\cr}
+}
+\value{
+[\code{numeric} | \code{matrix} | \code{data.frame}].
+}
+\description{
+Currently implemented for numeric vectors, numeric matrices and data.frame.
+For matrixes one can operate on rows or columns
+For data.frames, only the numeric columns are touched, all others are left unchanged.
+For constant vectors / rows / columns most methods fail, special behaviour for this
+case is implemented.
+
+The method also handles NAs in in \code{x} and leaves them untouched.
+}
+\seealso{
+\code{\link{scale}}
+}
+
diff --git a/man/optimizeSubInts.Rd b/man/optimizeSubInts.Rd
new file mode 100644
index 0000000..89adaf4
--- /dev/null
+++ b/man/optimizeSubInts.Rd
@@ -0,0 +1,40 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/optimizeSubInts.R
+\name{optimizeSubInts}
+\alias{optimizeSubInts}
+\title{Naive multi-start version of \code{\link{optimize}} for global optimization.}
+\usage{
+optimizeSubInts(f, interval, ..., lower = min(interval),
+ upper = max(interval), maximum = FALSE, tol = .Machine$double.eps^0.25,
+ nsub = 50L)
+}
+\arguments{
+\item{f}{See \code{\link{optimize}}.}
+
+\item{interval}{See \code{\link{optimize}}.}
+
+\item{...}{See \code{\link{optimize}}.}
+
+\item{lower}{See \code{\link{optimize}}.}
+
+\item{upper}{See \code{\link{optimize}}.}
+
+\item{maximum}{See \code{\link{optimize}}.}
+
+\item{tol}{See \code{\link{optimize}}.}
+
+\item{nsub}{[\code{integer(1)}]\cr
+Number of subintervals. A value of 1 implies normal \code{\link{optimize}} behavior.
+Default is 50L.}
+}
+\value{
+See \code{\link{optimize}}.
+}
+\description{
+The univariate \code{\link{optimize}} can stop at arbitrarily bad points when
+\code{f} is not unimodal. This functions mitigates this effect in a very naive way:
+\code{interval} is subdivided into \code{nsub} equally sized subintervals,
+\code{\link{optimize}} is run on all of them (and on the original big interval) and
+the best obtained point is returned.
+}
+
diff --git a/man/pause.Rd b/man/pause.Rd
new file mode 100644
index 0000000..99ebf41
--- /dev/null
+++ b/man/pause.Rd
@@ -0,0 +1,12 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/pause.R
+\name{pause}
+\alias{pause}
+\title{Pause in interactive mode and continue on <Enter>.}
+\usage{
+pause()
+}
+\description{
+Pause in interactive mode and continue on <Enter>.
+}
+
diff --git a/man/printStrToChar.Rd b/man/printStrToChar.Rd
new file mode 100644
index 0000000..54247ae
--- /dev/null
+++ b/man/printStrToChar.Rd
@@ -0,0 +1,27 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/printStrToChar.R
+\name{printStrToChar}
+\alias{printStrToChar}
+\title{Print \code{str(x)} of an object to a string / character vector.}
+\usage{
+printStrToChar(x, collapse = "\\n")
+}
+\arguments{
+\item{x}{[any]\cr
+Object to print}
+
+\item{collapse}{[\code{character(1)}]\cr
+Used to collapse multiple lines.
+\code{NULL} means no collapsing, vector is returned.
+Default is \dQuote{\\n}.}
+}
+\value{
+[\code{character}].
+}
+\description{
+Print \code{str(x)} of an object to a string / character vector.
+}
+\examples{
+printStrToChar(iris)
+}
+
diff --git a/man/printToChar.Rd b/man/printToChar.Rd
new file mode 100644
index 0000000..c4f6694
--- /dev/null
+++ b/man/printToChar.Rd
@@ -0,0 +1,28 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/printToChar.R
+\name{printToChar}
+\alias{printToChar}
+\title{Prints object to a string / character vector.}
+\usage{
+printToChar(x, collapse = "\\n")
+}
+\arguments{
+\item{x}{[any]\cr
+Object to print}
+
+\item{collapse}{[\code{character(1)}]\cr
+Used to collapse multiple lines.
+\code{NULL} means no collapsing, vector is returned.
+Default is \dQuote{\\n}.}
+}
+\value{
+[\code{character}].
+}
+\description{
+Prints object to a string / character vector.
+}
+\examples{
+x = data.frame(a = 1:2, b = 3:4)
+str(printToChar(x))
+}
+
diff --git a/man/rangeVal.Rd b/man/rangeVal.Rd
new file mode 100644
index 0000000..4e3c126
--- /dev/null
+++ b/man/rangeVal.Rd
@@ -0,0 +1,24 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/rangeVal.R
+\name{rangeVal}
+\alias{rangeVal}
+\title{Calculate range statistic.}
+\usage{
+rangeVal(x, na.rm = FALSE)
+}
+\arguments{
+\item{x}{[\code{numeric}]\cr
+The vector.}
+
+\item{na.rm}{[\code{logical(1)}]\cr
+If \code{FALSE}, NA is returned if an NA is encountered in \code{x}.
+If \code{TRUE}, NAs are disregarded.
+Default is \code{FALSE}}
+}
+\value{
+[\code{numeric(1)}].
+}
+\description{
+A simple wrapper for \code{diff(range(x))}, so \code{max(x) - min(x)}.
+}
+
diff --git a/man/requirePackages.Rd b/man/requirePackages.Rd
new file mode 100644
index 0000000..d94d6f9
--- /dev/null
+++ b/man/requirePackages.Rd
@@ -0,0 +1,59 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/requirePackages.R
+\name{requirePackages}
+\alias{requirePackages}
+\title{Require some packages.}
+\usage{
+requirePackages(packs, min.versions = NULL, why = "", stop = TRUE,
+ suppress.warnings = FALSE, default.method = "attach")
+}
+\arguments{
+\item{packs}{[\code{character}]\cr
+Names of packages.
+If a package name is prefixed with \dQuote{!}, it will be attached using \code{\link[base]{require}}.
+If a package name is prefixed with \dQuote{_}, its namespace will be loaded using \code{\link[base]{requireNamespace}}.
+If there is no prefix, argument \code{default.method} determines how to deal with package loading.}
+
+\item{min.versions}{[\code{character}]\cr
+A char vector specifying required minimal version numbers for a subset of packages in \code{packs}.
+Must be named and all names must be in \code{packs}.
+The only exception is when \code{packs} is only a single string, then you are allowed to pass
+an unnamed version string here.
+Default is \code{NULL}, meaning no special version requirements}
+
+\item{why}{[\code{character(1)}]\cr
+Short string explaining why packages are required.
+Default is an empty string.}
+
+\item{stop}{[\code{logical(1)}]\cr
+Should an exception be thrown for missing packages?
+Default is \code{TRUE}.}
+
+\item{suppress.warnings}{[\code{logical(1)}]\cr
+Should warnings be supressed while requiring?
+Default is \code{FALSE}.}
+
+\item{default.method}{[\code{character(1)}]\cr
+If the packages are not explicitly prefixed with \dQuote{!} or \dQuote{_},
+this arguments determines the default. Possible values are \dQuote{attach} and
+\dQuote{load}.
+Note that the default is \dQuote{attach}, but this might/will change in a future version, so
+please make sure to always explicitly set this.}
+}
+\value{
+[\code{logical}]. Named logical vector describing which packages could be loaded (with required version).
+ Same length as \code{packs}.
+}
+\description{
+Packages are loaded either via \code{\link{requireNamespace}} or \code{\link{require}}.
+
+If some packages could not be loaded and \code{stop} is \code{TRUE}
+the following exception is thrown:
+\dQuote{For <why> please install the following packages: <missing packages>}.
+If \code{why} is \code{NULL} the message is:
+\dQuote{Please install the following packages: <missing packages>}.
+}
+\examples{
+requirePackages(c("BBmisc", "base"), why = "BBmisc example")
+}
+
diff --git a/man/rowLapply.Rd b/man/rowLapply.Rd
new file mode 100644
index 0000000..e14db2d
--- /dev/null
+++ b/man/rowLapply.Rd
@@ -0,0 +1,50 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/rowLapply.R
+\name{rowLapply}
+\alias{rowLapply}
+\alias{rowSapply}
+\title{Apply function to rows of a data frame.}
+\usage{
+rowLapply(df, fun, ..., unlist = FALSE)
+
+rowSapply(df, fun, ..., unlist = FALSE, simplify = TRUE, use.names = TRUE)
+}
+\arguments{
+\item{df}{[\code{data.frame}]\cr
+Data frame.}
+
+\item{fun}{[\code{function}]\cr
+Function to apply. Rows are passed as list or vector,
+depending on argument \code{unlist}, as first argument.}
+
+\item{...}{[\code{ANY}]\cr
+Additional arguments for \code{fun}.}
+
+\item{unlist}{[\code{logical(1)}]\cr
+Unlist the row? Note that automatic conversion may be triggered for
+lists of mixed data types
+Default is \code{FALSE}.}
+
+\item{simplify}{[\code{logical(1)} | character(1)]\cr
+Should the result be simplified?
+See \code{\link{sapply}}.
+If \dQuote{cols}, we expect the call results to be vectors of the same length and they are
+arranged as the columns of the resulting matrix.
+If \dQuote{rows}, likewise, but rows of the resulting matrix.
+Default is \code{TRUE}.}
+
+\item{use.names}{[\code{logical(1)}]\cr
+Should result be named by the row names of \code{df}?
+Default is \code{TRUE}.}
+}
+\value{
+[\code{list} or simplified object]. Length is \code{nrow(df)}.
+}
+\description{
+Just like an \code{\link[base]{lapply}} on data frames,
+but on the rows.
+}
+\examples{
+ rowLapply(iris, function(x) x$Sepal.Length + x$Sepal.Width)
+}
+
diff --git a/man/save2.Rd b/man/save2.Rd
new file mode 100644
index 0000000..a032677
--- /dev/null
+++ b/man/save2.Rd
@@ -0,0 +1,41 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/save2.R
+\name{save2}
+\alias{save2}
+\title{Save multiple objects to a file.}
+\usage{
+save2(file, ..., ascii = FALSE, version = NULL, compress = !ascii,
+ compression_level, eval.promises = TRUE, precheck = TRUE)
+}
+\arguments{
+\item{file}{File to save.}
+
+\item{...}{[\code{any}]\cr
+Will be converted to an environment and then passed to \code{\link[base]{save}}.}
+
+\item{ascii}{See help of \code{\link[base]{save}}.}
+
+\item{version}{See help of \code{\link[base]{save}}.}
+
+\item{compress}{See help of \code{\link[base]{save}}.}
+
+\item{compression_level}{See help of \code{\link[base]{save}}.}
+
+\item{eval.promises}{See help of \code{\link[base]{save}}.}
+
+\item{precheck}{See help of \code{\link[base]{save}}.}
+}
+\value{
+See help of \code{\link[base]{save}}.
+}
+\description{
+A simple wrapper for \code{\link[base]{save}}. Understands key = value syntax to save
+objects using arbitrary variable names. All options of \code{\link[base]{save}},
+except \code{list} and \code{envir}, are available and passed to
+\code{\link[base]{save}}.
+}
+\examples{
+x = 1
+save2(y = x, file = tempfile())
+}
+
diff --git a/man/seq_row.Rd b/man/seq_row.Rd
new file mode 100644
index 0000000..45daa9a
--- /dev/null
+++ b/man/seq_row.Rd
@@ -0,0 +1,28 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/seq.R
+\name{seq_row}
+\alias{seq_col}
+\alias{seq_row}
+\title{Generate sequences along rows or cols.}
+\usage{
+seq_row(x)
+
+seq_col(x)
+}
+\arguments{
+\item{x}{[\code{data.frame} | \code{matrix}]\cr
+Data frame, matrix or any object which supports \code{\link[base]{nrow}}
+or \code{\link[base]{ncol}}, respectively.}
+}
+\value{
+Vector of type [\code{integer}].
+}
+\description{
+A simple convenience wrapper around \code{\link[base]{seq_len}}.
+}
+\examples{
+data(iris)
+seq_row(iris)
+seq_col(iris)
+}
+
diff --git a/man/setAttribute.Rd b/man/setAttribute.Rd
new file mode 100644
index 0000000..8886548
--- /dev/null
+++ b/man/setAttribute.Rd
@@ -0,0 +1,28 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/setAttribute.R
+\name{setAttribute}
+\alias{setAttribute}
+\title{A wrapper for \code{attr(x, which) = y}.}
+\usage{
+setAttribute(x, which, value)
+}
+\arguments{
+\item{x}{[any]\cr
+Your object.}
+
+\item{which}{[\code{character(1)}]\cr
+Name of the attribute to set}
+
+\item{value}{[\code{ANY}]\cr
+Value for the attribute.}
+}
+\value{
+Changed object \code{x}.
+}
+\description{
+A wrapper for \code{attr(x, which) = y}.
+}
+\examples{
+setAttribute(list(), "foo", 1)
+}
+
diff --git a/man/setClasses.Rd b/man/setClasses.Rd
new file mode 100644
index 0000000..a3cdbda
--- /dev/null
+++ b/man/setClasses.Rd
@@ -0,0 +1,25 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/setClasses.R
+\name{setClasses}
+\alias{setClasses}
+\title{A wrapper for \code{class(x) = classes}.}
+\usage{
+setClasses(x, classes)
+}
+\arguments{
+\item{x}{[any]\cr
+Your object.}
+
+\item{classes}{[\code{character}]\cr
+New classes.}
+}
+\value{
+Changed object \code{x}.
+}
+\description{
+A wrapper for \code{class(x) = classes}.
+}
+\examples{
+setClasses(list(), c("foo1", "foo2"))
+}
+
diff --git a/man/setRowNames.Rd b/man/setRowNames.Rd
new file mode 100644
index 0000000..0d98899
--- /dev/null
+++ b/man/setRowNames.Rd
@@ -0,0 +1,28 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/setRowColNames.R
+\name{setRowNames}
+\alias{setColNames}
+\alias{setRowNames}
+\title{Wrapper for \code{rownames(x) = y}, \code{colnames(x) = y}.}
+\usage{
+setRowNames(x, names)
+
+setColNames(x, names)
+}
+\arguments{
+\item{x}{[\code{matrix} | \code{data.frame}]\cr
+Matrix or data.frame.}
+
+\item{names}{[\code{character}]\cr
+New names for rows / columns.}
+}
+\value{
+Changed object \code{x}.
+}
+\description{
+Wrapper for \code{rownames(x) = y}, \code{colnames(x) = y}.
+}
+\examples{
+setColNames(matrix(1:4, 2, 2), c("a", "b"))
+}
+
diff --git a/man/setValue.Rd b/man/setValue.Rd
new file mode 100644
index 0000000..5d1576d
--- /dev/null
+++ b/man/setValue.Rd
@@ -0,0 +1,25 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/setValue.R
+\name{setValue}
+\alias{setValue}
+\title{Set a list element to a new value.}
+\usage{
+setValue(obj, index, newval)
+}
+\arguments{
+\item{obj}{[\code{list}]\cr}
+
+\item{index}{[\code{character} | \code{integer}]\cr
+Index or indices where to insert the new values.}
+
+\item{newval}{[any]\cr
+Inserted elements(s).
+Has to be a list if \code{index} is a vector.}
+}
+\value{
+[\code{list}]
+}
+\description{
+This wrapper supports setting elements to \code{NULL}.
+}
+
diff --git a/man/sortByCol.Rd b/man/sortByCol.Rd
new file mode 100644
index 0000000..1125773
--- /dev/null
+++ b/man/sortByCol.Rd
@@ -0,0 +1,29 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/sortByCol.R
+\name{sortByCol}
+\alias{sortByCol}
+\title{Sort the rows of a data.frame according to one or more columns.}
+\usage{
+sortByCol(x, col, asc = TRUE)
+}
+\arguments{
+\item{x}{[\code{data.frame}]\cr
+Data.frame to sort.}
+
+\item{col}{[\code{character}]\cr
+One or more column names to sort \code{x} by.
+In order of preference.}
+
+\item{asc}{[\code{logical}]\cr
+Sort ascending (or descending)?
+One value per entry of \code{col}.
+If a scalar logical is passed, it is replicated.
+Default is \code{TRUE}.}
+}
+\value{
+[\code{data.frame}].
+}
+\description{
+Sort the rows of a data.frame according to one or more columns.
+}
+
diff --git a/man/splitPath.Rd b/man/splitPath.Rd
new file mode 100644
index 0000000..a8cc2c7
--- /dev/null
+++ b/man/splitPath.Rd
@@ -0,0 +1,22 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/splitPath.R
+\name{splitPath}
+\alias{splitPath}
+\title{Split a path into components}
+\usage{
+splitPath(path)
+}
+\arguments{
+\item{path}{[\code{character(1)}]\cr
+Path to split as string}
+}
+\value{
+\code{named list}: List with components \dQuote{drive} (\code{character(1)}
+ and \dQuote{path} (\code{character(n)}.
+}
+\description{
+The first normalized path is split on forward and backward slashes and its components returned as
+character vector. The drive or network home are extracted separately on windows systems and
+empty on all other systems.
+}
+
diff --git a/man/splitTime.Rd b/man/splitTime.Rd
new file mode 100644
index 0000000..ee2194e
--- /dev/null
+++ b/man/splitTime.Rd
@@ -0,0 +1,30 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/splitTime.R
+\name{splitTime}
+\alias{splitTime}
+\title{Split seconds into handy chunks of time.}
+\usage{
+splitTime(seconds, unit = "years")
+}
+\arguments{
+\item{seconds}{[\code{numeric(1)}]\cr
+Number of seconds. If not an integer, it is rounded down.}
+
+\item{unit}{[\code{character(1)}]\cr
+Largest unit to split seconds into.
+Must be one of: \code{c("years", "days", "hours", "minutes", "seconds")}.
+Default is \dQuote{years}.}
+}
+\value{
+[\code{numeric(5)}]. A named vector containing the
+\dQuote{years}, \dQuote{days}, \dQuote{hours}, \dQuote{minutes}
+and \dQuote{seconds}. Units larger than the given \code{unit} are
+\code{NA}.
+}
+\description{
+Note that a year is simply defined as exactly 365 days.
+}
+\examples{
+splitTime(1000)
+}
+
diff --git a/man/stopf.Rd b/man/stopf.Rd
new file mode 100644
index 0000000..26d320a
--- /dev/null
+++ b/man/stopf.Rd
@@ -0,0 +1,30 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/stopf.R
+\name{stopf}
+\alias{stopf}
+\title{Wrapper for stop and sprintf.}
+\usage{
+stopf(..., warning.length = 8170L)
+}
+\arguments{
+\item{...}{[any]\cr
+See \code{\link{sprintf}}.}
+
+\item{warning.length}{[\code{integer(1)}]\cr
+Number of chars after which the error message
+gets truncated, see ?options.
+Default is 8170.}
+}
+\value{
+Nothing.
+}
+\description{
+A wrapper for \code{\link{stop}} with \code{\link{sprintf}} applied to the arguments.
+Notable difference is that error messages are not truncated to 1000 characters
+by default.
+}
+\examples{
+err = "an error."
+try(stopf("This is \%s", err))
+}
+
diff --git a/man/strrepeat.Rd b/man/strrepeat.Rd
new file mode 100644
index 0000000..0181d18
--- /dev/null
+++ b/man/strrepeat.Rd
@@ -0,0 +1,28 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/strrepeat.R
+\name{strrepeat}
+\alias{strrepeat}
+\title{Repeat and join a string}
+\usage{
+strrepeat(x, n, sep = "")
+}
+\arguments{
+\item{x}{[character]\cr
+Vector of characters.}
+
+\item{n}{[\code{integer(1)}]\cr
+Times the vector \code{x} is repeated.}
+
+\item{sep}{[\code{character(1)}]\cr
+Separator to use to collapse the vector of characters.}
+}
+\value{
+\code{character(1)}.
+}
+\description{
+Repeat and join a string
+}
+\examples{
+strrepeat("x", 3)
+}
+
diff --git a/man/suppressAll.Rd b/man/suppressAll.Rd
new file mode 100644
index 0000000..1c11b19
--- /dev/null
+++ b/man/suppressAll.Rd
@@ -0,0 +1,27 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/suppressAll.R
+\name{suppressAll}
+\alias{suppressAll}
+\title{Suppresses all output except for errors.}
+\usage{
+suppressAll(expr)
+}
+\arguments{
+\item{expr}{[valid R expression]\cr
+Expression.}
+}
+\value{
+Return value of expression invisibly.
+}
+\description{
+Evaluates an expression and suppresses all output except for errors,
+meaning: prints, messages, warnings and package startup messages.
+}
+\examples{
+suppressAll({
+ print("foo")
+ message("foo")
+ warning("foo")
+})
+}
+
diff --git a/man/symdiff.Rd b/man/symdiff.Rd
new file mode 100644
index 0000000..54f671c
--- /dev/null
+++ b/man/symdiff.Rd
@@ -0,0 +1,22 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/symdiff.R
+\name{symdiff}
+\alias{symdiff}
+\title{Calculates symmetric set difference between two sets.}
+\usage{
+symdiff(x, y)
+}
+\arguments{
+\item{x}{[\code{vector}]\cr
+Set 1.}
+
+\item{y}{[\code{vector}]\cr
+Set 2.}
+}
+\value{
+[\code{vector}].
+}
+\description{
+Calculates symmetric set difference between two sets.
+}
+
diff --git a/man/system3.Rd b/man/system3.Rd
new file mode 100644
index 0000000..58fba1e
--- /dev/null
+++ b/man/system3.Rd
@@ -0,0 +1,36 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/system3.R
+\name{system3}
+\alias{system3}
+\title{Wrapper for system2 with better return type and errorhandling.}
+\usage{
+system3(command, args = character(0L), stdout = "", stderr = "",
+ wait = TRUE, ..., stop.on.exit.code = wait)
+}
+\arguments{
+\item{command}{See \code{\link{system2}}.}
+
+\item{args}{See \code{\link{system2}}.}
+
+\item{stdout}{See \code{\link{system2}}.}
+
+\item{stderr}{See \code{\link{system2}}.}
+
+\item{wait}{See \code{\link{system2}}.}
+
+\item{...}{Further arguments passed to \code{\link{system2}}.}
+
+\item{stop.on.exit.code}{[\code{logical(1)}]\cr
+Should an exception be thrown if an exit code greater 0 is generated?
+Can only be used if \code{wait} is \code{TRUE}.
+Default is \code{wait}.}
+}
+\value{
+[\code{list}].
+ \item{exit.code [integer(1)]}{Exit code of command. Given if wait is \code{TRUE}, otherwise \code{NA}. 0L means success. 127L means command was not found}
+ \item{output [character]}{Output of command on streams. Only given is \code{stdout} or \code{stderr} was set to \code{TRUE}, otherwise \code{NA}.}
+}
+\description{
+Wrapper for \code{\link{system2}} with better return type and errorhandling.
+}
+
diff --git a/man/toRangeStr.Rd b/man/toRangeStr.Rd
new file mode 100644
index 0000000..b28c1af
--- /dev/null
+++ b/man/toRangeStr.Rd
@@ -0,0 +1,32 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/toRangeStr.R
+\name{toRangeStr}
+\alias{toRangeStr}
+\title{Convert a numerical vector into a range string.}
+\usage{
+toRangeStr(x, range.sep = " - ", block.sep = ", ")
+}
+\arguments{
+\item{x}{[\code{integer}]\cr
+Vector to convert into a range string.}
+
+\item{range.sep}{[\code{character(1)}]\cr
+Separator between the first and last element of a range of consecutive
+elements in \code{x}.
+Default is \dQuote{ - }.}
+
+\item{block.sep}{[\code{character(1)}]\cr
+Separator between non consecutive elements of \code{x} or ranges.
+Default is \dQuote{, }.}
+}
+\value{
+[\code{character(1)}]
+}
+\description{
+Convert a numerical vector into a range string.
+}
+\examples{
+x = sample(1:10, 7)
+toRangeStr(x)
+}
+
diff --git a/man/vlapply.Rd b/man/vlapply.Rd
new file mode 100644
index 0000000..a0dfbca
--- /dev/null
+++ b/man/vlapply.Rd
@@ -0,0 +1,39 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/vapply.R
+\name{vlapply}
+\alias{vcapply}
+\alias{viapply}
+\alias{vlapply}
+\alias{vnapply}
+\title{Apply a function with a predefined return value}
+\usage{
+vlapply(x, fun, ..., use.names = TRUE)
+
+viapply(x, fun, ..., use.names = TRUE)
+
+vnapply(x, fun, ..., use.names = TRUE)
+
+vcapply(x, fun, ..., use.names = TRUE)
+}
+\arguments{
+\item{x}{[\code{vector} or \code{list}]\cr
+Object to apply function on.}
+
+\item{fun}{[\code{function}]\cr
+Function to apply on each element of \code{x}.}
+
+\item{...}{[\code{ANY}]\cr
+Additional arguments for \code{fun}.}
+
+\item{use.names}{[\code{logical(1)}]\cr
+Should result be named?
+Default is \code{TRUE}.}
+}
+\description{
+These are just wrappers around \code{\link[base]{vapply}} with
+argument \code{FUN.VALUE} set.
+The function is expected to return a single \code{logical}, \code{integer},
+\code{numeric} or \code{character} value, depending on the second letter
+of the function name.
+}
+
diff --git a/man/warningf.Rd b/man/warningf.Rd
new file mode 100644
index 0000000..d5ce1f8
--- /dev/null
+++ b/man/warningf.Rd
@@ -0,0 +1,32 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/warningf.R
+\name{warningf}
+\alias{warningf}
+\title{Wrapper for warning and sprintf.}
+\usage{
+warningf(..., immediate = TRUE, warning.length = 8170L)
+}
+\arguments{
+\item{...}{[any]\cr
+See \code{\link{sprintf}}.}
+
+\item{immediate}{[\code{logical(1)}]\cr
+See \code{\link{warning}}.
+Default is \code{TRUE}.}
+
+\item{warning.length}{[\code{integer(1)}]\cr
+Number of chars after which the warning message
+gets truncated, see ?options.
+Default is 8170.}
+}
+\value{
+Nothing.
+}
+\description{
+A wrapper for \code{\link{warning}} with \code{\link{sprintf}} applied to the arguments.
+}
+\examples{
+msg = "a warning"
+warningf("this is \%s", msg)
+}
+
diff --git a/man/which.first.Rd b/man/which.first.Rd
new file mode 100644
index 0000000..ca24023
--- /dev/null
+++ b/man/which.first.Rd
@@ -0,0 +1,32 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/which.first.R
+\name{which.first}
+\alias{which.first}
+\alias{which.last}
+\title{Find the index of first/last \code{TRUE} value in a logical vector.}
+\usage{
+which.first(x, use.names = TRUE)
+
+which.last(x, use.names = TRUE)
+}
+\arguments{
+\item{x}{[\code{logical}]\cr
+Logical vector.}
+
+\item{use.names}{[\code{logical(1)}]\cr
+If \code{TRUE} and \code{x} is named, the result is also
+named.}
+}
+\value{
+[\code{integer(1)} | \code{integer(0)}].
+ Returns the index of the first/last \code{TRUE} value in \code{x} or
+ an empty integer vector if none is found.
+}
+\description{
+Find the index of first/last \code{TRUE} value in a logical vector.
+}
+\examples{
+ which.first(c(FALSE, TRUE))
+ which.last(c(FALSE, FALSE))
+}
+
diff --git a/src/getMaxColRowIndex.c b/src/getMaxColRowIndex.c
new file mode 100644
index 0000000..e884e63
--- /dev/null
+++ b/src/getMaxColRowIndex.c
@@ -0,0 +1,33 @@
+#include "getMaxColRowIndex.h"
+#include "getMaxIndex.h"
+#include "macros.h"
+
+SEXP c_getMaxIndexOfRows(SEXP s_x, SEXP s_ties_method, SEXP s_na_rm) {
+ int ties_method = asInteger(s_ties_method);
+ Rboolean na_rm = asLogical(s_na_rm);
+ UNPACK_REAL_MATRIX(s_x, x, nrow_x, ncol_x);
+ SEXP s_ret = PROTECT(allocVector(INTSXP, nrow_x));
+ int* ret = INTEGER(s_ret);
+ GetRNGstate();
+ for (R_len_t i = 0; i < nrow_x; i++) {
+ ret[i] = get_max_index(x + i, ncol_x, nrow_x, ties_method, na_rm);
+ }
+ PutRNGstate();
+ UNPROTECT(1); /* s_ret */
+ return s_ret;
+}
+
+SEXP c_getMaxIndexOfCols(SEXP s_x, SEXP s_ties_method, SEXP s_na_rm) {
+ int ties_method = asInteger(s_ties_method);
+ Rboolean na_rm = asInteger(s_na_rm);
+ UNPACK_REAL_MATRIX(s_x, x, nrow_x, ncol_x);
+ SEXP s_ret = PROTECT(allocVector(INTSXP, ncol_x));
+ int* ret = INTEGER(s_ret);
+ GetRNGstate();
+ for (R_len_t i = 0; i < ncol_x; ++i) {
+ ret[i] = get_max_index(x + i*nrow_x, nrow_x, 1, ties_method, na_rm);
+ }
+ PutRNGstate();
+ UNPROTECT(1); /* s_ret */
+ return s_ret;
+}
diff --git a/src/getMaxColRowIndex.h b/src/getMaxColRowIndex.h
new file mode 100644
index 0000000..56ff7d2
--- /dev/null
+++ b/src/getMaxColRowIndex.h
@@ -0,0 +1,11 @@
+#ifndef GETMAXCOLROWINDEX_H
+#define GETMAXCOLROWINDEX_H
+
+#include <R.h>
+#include <Rinternals.h>
+#include <Rdefines.h>
+
+SEXP c_getMaxIndexOfRows(SEXP s_x, SEXP s_ties_method, SEXP s_na_rm);
+SEXP c_getMaxIndexOfCols(SEXP s_x, SEXP s_ties_method, SEXP s_na_rm);
+
+#endif
diff --git a/src/getMaxIndex.c b/src/getMaxIndex.c
new file mode 100644
index 0000000..3acdad0
--- /dev/null
+++ b/src/getMaxIndex.c
@@ -0,0 +1,58 @@
+#include "getMaxIndex.h"
+#include "macros.h"
+
+/*
+ Get index of maximal element of double array x (1-based).
+
+ Allows to only consider a subset of elements, separated by regular gaps.
+ If NANs or NAs are encountered
+
+ x : double pointer to data
+ n : length of x
+ stride : step size to walk thru x
+
+ return : Index of maximal element (1-based) or
+ -1 if we did not find a maximal elemnt (empty vector or only removed NAs)
+*/
+int get_max_index(double *x, R_len_t n, R_len_t step, int ties_method, Rboolean na_rm) {
+ R_len_t i;
+ int max_index = -2;
+ int number_of_ties = 0;
+ double max_value = -DBL_MAX, current_value;
+
+ for (i = 0; i < n; ++i) {
+ current_value = x[i*step];
+ if (!na_rm && ISNAN(current_value))
+ return NA_INTEGER;
+ if (current_value > max_value) {
+ number_of_ties = 1;
+ max_value = current_value;
+ max_index = i;
+ } else if (current_value == max_value) {
+ if (ties_method == 1) {
+ ++number_of_ties;
+ if (number_of_ties * unif_rand() < 1.0)
+ max_index = i;
+ } else if (ties_method == 3) {
+ max_index = i;
+ }
+ }
+ }
+ /* make index 1-based */
+ return max_index + 1;
+}
+
+SEXP c_getMaxIndex(SEXP s_x, SEXP s_ties_method, SEXP s_na_rm) {
+ if (length(s_x) == 0)
+ return NEW_INTEGER(0);
+ int ties_method = asInteger(s_ties_method);
+ Rboolean na_rm = asInteger(s_na_rm);
+ UNPACK_REAL_VECTOR(s_x, x, len_x);
+ GetRNGstate();
+ int index = get_max_index(x, len_x, 1, ties_method, na_rm);
+ PutRNGstate();
+ if (index == -1)
+ return NEW_INTEGER(0);
+ else
+ return ScalarInteger(index);
+}
diff --git a/src/getMaxIndex.h b/src/getMaxIndex.h
new file mode 100644
index 0000000..eeac10b
--- /dev/null
+++ b/src/getMaxIndex.h
@@ -0,0 +1,11 @@
+#ifndef GETMAXINDEX_H
+#define GETMAXINDEX_H
+
+#include <R.h>
+#include <Rinternals.h>
+#include <Rdefines.h>
+
+int get_max_index(double *x, R_len_t n, R_len_t step, int ties_method, Rboolean na_rm);
+SEXP c_getMaxIndex(SEXP s_x, SEXP s_ties_method, SEXP s_na_rm);
+
+#endif
diff --git a/src/itostr.c b/src/itostr.c
new file mode 100644
index 0000000..7b666b9
--- /dev/null
+++ b/src/itostr.c
@@ -0,0 +1,28 @@
+#include <string.h>
+#include <math.h>
+#include "itostr.h"
+
+static const char base36[37] = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+SEXP itostr (SEXP x, SEXP base) {
+ const R_len_t n = length(x);
+ const R_len_t b = INTEGER(base)[0];
+ SEXP res = PROTECT(allocVector(STRSXP, n));
+
+ const R_len_t buflen = ceil(log(exp2(64) / log(b)));
+ char buffer[buflen + 1];
+ buffer[buflen] = '\0';
+
+ for (R_len_t i = 0; i < n; i++) {
+ R_len_t offset = buflen;
+ int xi = INTEGER(x)[i];
+ do {
+ buffer[--offset] = base36[xi % b];
+ } while (xi /= b);
+
+ SET_STRING_ELT(res, i, mkChar(&buffer[offset]));
+ }
+
+ UNPROTECT(1);
+ return res;
+}
diff --git a/src/itostr.h b/src/itostr.h
new file mode 100644
index 0000000..de231a3
--- /dev/null
+++ b/src/itostr.h
@@ -0,0 +1,10 @@
+#ifndef BBMISC_ITOSTR_H_
+#define BBMISC_ITOSTR_H_
+
+#include <R.h>
+#include <Rinternals.h>
+#include <Rdefines.h>
+
+SEXP itostr(SEXP, SEXP);
+
+#endif
diff --git a/src/macros.h b/src/macros.h
new file mode 100644
index 0000000..8550217
--- /dev/null
+++ b/src/macros.h
@@ -0,0 +1,17 @@
+#ifndef FOO_MACROS_H
+#define FOO_MACROS_H
+
+#include <R.h>
+#include <Rinternals.h>
+#include <Rdefines.h>
+
+#define UNPACK_REAL_VECTOR(S, D, N) \
+ double *D = REAL(S); \
+ const R_len_t N = length(S);
+
+#define UNPACK_REAL_MATRIX(S, D, N, K) \
+ double *D = REAL(S); \
+ const R_len_t N = nrows(S); \
+ const R_len_t K = ncols(S);
+
+#endif
diff --git a/src/which_first.c b/src/which_first.c
new file mode 100644
index 0000000..5269bca
--- /dev/null
+++ b/src/which_first.c
@@ -0,0 +1,49 @@
+#include "which_first.h"
+
+static inline SEXP named_return(R_len_t ind, SEXP names) {
+ if (isNull(names))
+ return ScalarInteger(ind + 1);
+
+ SEXP res;
+ PROTECT(res = ScalarInteger(ind + 1));
+ SET_NAMES(res, ScalarString(STRING_ELT(names, ind)));
+ UNPROTECT(1);
+ return res;
+}
+
+SEXP c_which_first(SEXP x, SEXP use_names) {
+ if (!isLogical(x))
+ error("Argument 'x' must be logical");
+ if (!isLogical(use_names) || length(use_names) != 1)
+ error("Argument 'use.names' must be a flag");
+ const R_len_t n = length(x);
+ int *xp = LOGICAL(x);
+
+ for (R_len_t i = 0; i < n; i++) {
+ if (xp[i] != NA_LOGICAL && xp[i]) {
+ if (LOGICAL(use_names)[0])
+ return named_return(i, GET_NAMES(x));
+ else
+ return ScalarInteger(i+1);
+ }
+ }
+ return allocVector(INTSXP, 0);
+}
+
+SEXP c_which_last(SEXP x, SEXP use_names) {
+ if (!isLogical(x))
+ error("Argument 'x' must be logical");
+ if (!isLogical(use_names) || length(use_names) != 1)
+ error("Argument 'use.names' must be a flag");
+ int *xp = LOGICAL(x);
+
+ for (R_len_t i = length(x) - 1; i >= 0; i--) {
+ if (xp[i] != NA_LOGICAL && xp[i]) {
+ if (LOGICAL(use_names)[0])
+ return named_return(i, GET_NAMES(x));
+ else
+ return ScalarInteger(i+1);
+ }
+ }
+ return allocVector(INTSXP, 0);
+}
diff --git a/src/which_first.h b/src/which_first.h
new file mode 100644
index 0000000..7358837
--- /dev/null
+++ b/src/which_first.h
@@ -0,0 +1,11 @@
+#ifndef BBMISC_WHICH_FIRST_H_
+#define BBMISC_WHICH_FIRST_H_
+
+#include <R.h>
+#include <Rinternals.h>
+#include <Rdefines.h>
+
+SEXP c_which_first(SEXP, SEXP);
+SEXP c_which_last(SEXP, SEXP);
+
+#endif
diff --git a/tests/run-all.R b/tests/run-all.R
new file mode 100644
index 0000000..015faf9
--- /dev/null
+++ b/tests/run-all.R
@@ -0,0 +1,2 @@
+library(testthat)
+test_check("BBmisc")
diff --git a/tests/testthat/test_addClasses.R b/tests/testthat/test_addClasses.R
new file mode 100644
index 0000000..d5abe76
--- /dev/null
+++ b/tests/testthat/test_addClasses.R
@@ -0,0 +1,9 @@
+context("addClasses")
+
+test_that("addClasses", {
+ x = list(a=1)
+ x = addClasses(x, "foo1")
+ expect_equal(x, structure(list(a=1), class=c("foo1", "list")))
+ x = addClasses(x, c("foo2", "foo3"))
+ expect_equal(x, structure(list(a=1), class=c("foo2", "foo3", "foo1", "list")))
+})
diff --git a/tests/testthat/test_asMatrix.R b/tests/testthat/test_asMatrix.R
new file mode 100644
index 0000000..3fd9252
--- /dev/null
+++ b/tests/testthat/test_asMatrix.R
@@ -0,0 +1,78 @@
+
+context("asMatrix")
+
+test_that("asMatrix", {
+ # empty
+ expect_equal(
+ asMatrixCols(list()),
+ matrix(0, nrow = 0L, ncol = 0L)
+ )
+ expect_equal(
+ asMatrixRows(list()),
+ matrix(0, nrow = 0L, ncol = 0L)
+ )
+
+ # normal
+ expect_equal(
+ asMatrixCols(list(c(1, 2), c(3, 3), c(4, 4))),
+ matrix(c(1, 2, 3, 3, 4, 4), nrow = 2, ncol = 3, byrow = FALSE)
+ )
+ expect_equal(
+ asMatrixRows(list(c(1, 2), c(3, 3), c(4, 4))),
+ matrix(c(1, 2, 3, 3, 4, 4), nrow = 3, ncol = 2, byrow = TRUE)
+ )
+
+ # names
+ expect_equal(
+ asMatrixCols(list(a = c(1, 2), b = c(3, 3), c = c(4, 4))),
+ setColNames(matrix(c(1, 2, 3, 3, 4, 4), nrow = 2, ncol = 3, byrow = FALSE), c("a", "b", "c"))
+ )
+ expect_equal(
+ asMatrixRows(list(a = c(1, 2), b = c(3, 3), c = c(4, 4))),
+ setRowNames(matrix(c(1, 2, 3, 3, 4, 4), nrow = 3, ncol = 2, byrow = TRUE), c("a", "b", "c"))
+ )
+ expect_equal(
+ asMatrixRows(list(a = c(x = 1, y = 2), b = c(3, 3), c = c(4, 4))),
+ setColNames(setRowNames(matrix(c(1, 2, 3, 3, 4, 4), nrow = 3, ncol = 2, byrow = TRUE),
+ c("a", "b", "c")), c("x", "y"))
+ )
+ # manually define rownames
+ expect_equal(
+ asMatrixCols(list(a = c(1, 2), b = c(3, 3), c = c(4, 4)), row.names = c("xx", "yy")),
+ setColNames(
+ setRowNames(matrix(c(1, 2, 3, 3, 4, 4), nrow = 2, ncol = 3, byrow = FALSE), c("xx", "yy")),
+ c("a", "b", "c"))
+ )
+ # manually define rownames, but use ints
+ expect_equal(
+ asMatrixCols(list(a = c(1, 2), b = c(3, 3), c = c(4, 4)), row.names = 1:2),
+ setColNames(
+ setRowNames(matrix(c(1, 2, 3, 3, 4, 4), nrow = 2, ncol = 3, byrow = FALSE), 1:2),
+ c("a", "b", "c"))
+ )
+ # manually define colnames
+ expect_equal(
+ asMatrixCols(list(a = c(1, 2), b = c(3, 3), c = c(4, 4)), col.names = c("xx", "yy", "zz")),
+ setColNames(
+ matrix(c(1, 2, 3, 3, 4, 4), nrow = 2, ncol = 3, byrow = FALSE),
+ c("xx", "yy", "zz"))
+ )
+ expect_equal(
+ asMatrixRows(list(a = c(1, 2), b = c(3, 3), c = c(4, 4)), col.names = c("xx", "yy")),
+ setRowNames(
+ setColNames(
+ matrix(c(1, 2, 3, 3, 4, 4), nrow = 3, ncol = 2, byrow = TRUE),
+ c("xx", "yy")
+ ),
+ c("a", "b", "c")
+ )
+ )
+ # manually define colnames, but use ints
+ expect_equal(
+ asMatrixCols(list(a = c(1, 2), b = c(3, 3), c = c(4, 4)), col.names = 1:3),
+ setColNames(
+ matrix(c(1, 2, 3, 3, 4, 4), nrow = 2, ncol = 3, byrow = FALSE),
+ 1:3)
+ )
+})
+
diff --git a/tests/testthat/test_asQuoted.R b/tests/testthat/test_asQuoted.R
new file mode 100644
index 0000000..6e89e9c
--- /dev/null
+++ b/tests/testthat/test_asQuoted.R
@@ -0,0 +1,8 @@
+context("asQuoted")
+
+test_that("asQuoted", {
+ e1 = asQuoted("x == 3")
+ e2 = quote(x == 3)
+ expect_equal(e1, e2)
+})
+
diff --git a/tests/testthat/test_binPack.R b/tests/testthat/test_binPack.R
new file mode 100644
index 0000000..230187d
--- /dev/null
+++ b/tests/testthat/test_binPack.R
@@ -0,0 +1,31 @@
+context("binPack")
+
+test_that("binPack", {
+ x = 1:10
+ res = binPack(x, 11L)
+ sums = sapply(split(x, res), sum)
+ expect_true(is.integer(res))
+ expect_equal(sums, setNames(rep(11L, 5L), 1:5))
+ expect_true(all(sums <= 11L))
+
+ x = sample(seq(from=0, to=1, by=0.01))
+ res = binPack(x, 1)
+ sums = sapply(split(x, res), sum)
+ expect_true(is.integer(res))
+ expect_true(all(head(sums, 50) == 1))
+
+ x = runif(20)
+ res = binPack(x, 1)
+ sums = sapply(split(x, res), sum)
+ expect_true(is.integer(res))
+ expect_true(all(sums < 1))
+
+ x = runif(5)
+ res = binPack(x, Inf)
+ expect_true(is.integer(res))
+ expect_true(length(res) == 5 && all(as.numeric(res) == 1))
+
+ expect_error(binPack(c(-5, 3)))
+ expect_error(binPack(c(1, 100), 10))
+ expect_error(binPack(c(1, Inf), 1))
+})
diff --git a/tests/testthat/test_btwn.R b/tests/testthat/test_btwn.R
new file mode 100644
index 0000000..b3cc7f8
--- /dev/null
+++ b/tests/testthat/test_btwn.R
@@ -0,0 +1,10 @@
+context("btwn")
+
+test_that("btwn", {
+ y = c(-1L,5L,Inf)
+ expect_equal(1L:3L %btwn% y, c(TRUE, TRUE, TRUE))
+ expect_equal(-2L:-1L %btwn% y, c(FALSE,TRUE))
+ y = 5L
+ expect_equal(5L %btwn% y, TRUE)
+ expect_equal(1L %btwn% y, FALSE)
+})
diff --git a/tests/testthat/test_capitalizeStrings.R b/tests/testthat/test_capitalizeStrings.R
new file mode 100644
index 0000000..c92f53e
--- /dev/null
+++ b/tests/testthat/test_capitalizeStrings.R
@@ -0,0 +1,15 @@
+context("capitalizeStrings")
+
+test_that("capitalizeStrings", {
+ testString = c("the taIl", "wags The dOg", "That Looks fuNny!")
+
+ expect_equal(capitalizeStrings(testString)
+ , c("The taIl", "Wags The dOg", "That Looks fuNny!"))
+ expect_equal(capitalizeStrings(testString, all.words = TRUE)
+ , c("The TaIl", "Wags The DOg", "That Looks FuNny!"))
+ expect_equal(capitalizeStrings(testString, all.words = TRUE, lower.back = TRUE)
+ , c("The Tail", "Wags The Dog", "That Looks Funny!"))
+ expect_equal(capitalizeStrings(testString, lower.back = TRUE)
+ , c("The tail", "Wags the dog", "That looks funny!"))
+})
+
diff --git a/tests/testthat/test_checkArg.R b/tests/testthat/test_checkArg.R
new file mode 100644
index 0000000..4b1012b
--- /dev/null
+++ b/tests/testthat/test_checkArg.R
@@ -0,0 +1,120 @@
+context("argument check")
+
+test_that("checkArg", {
+ f = function(x) checkArg(x, cl="integer", len=1)
+ f(1L)
+ expect_error(f(1))
+ expect_error(f(1:2))
+ f = function(x) checkArg(x, cl="integer", min.len=2)
+ f(1:2)
+ expect_error(f(1L))
+ f = function(x) checkArg(x, cl="integer", max.len=2)
+ f(1:2)
+ expect_error(f(1:3))
+ f = function(x) checkArg(x, cl="integer", len=2, na.ok=FALSE)
+ f(1:2)
+ expect_error(f(c(3L, NA)))
+ f = function(x) checkArg(x, cl="numeric", lower=2)
+ f(4:6)
+ expect_error(f(1:3))
+ f = function(x) checkArg(x, cl="numeric", upper=2)
+ f(1)
+ expect_error(f(3), "less than or equal 2")
+ f = function(x) checkArg(x, cl="numeric", lower=1, upper=2)
+ f(1); f(1.5); f(2)
+ expect_error(f(0), "greater than or equal 1")
+ expect_error(f(3), "less than or equal 2")
+
+ f = function(x) checkArg(x, cl="numeric", lower=1, upper=5)
+ f(1:5)
+ expect_error(f(0:5), "greater than or equal 1")
+ expect_error(f(1:6), "less than or equal 5")
+
+ f = function(x) checkArg(x, formals=c("foo", "bar"))
+ f(function(foo, bar) 1)
+ f(function(foo, bar, bla) 1)
+ expect_error(f(1), "must be of class function not: numeric")
+ expect_error(f(function(blubb) 1), "must have first formal args")
+ expect_error(f(function(foo) 1), "must have first formal args")
+
+ checkArg(1, "vector")
+ checkArg(1L, "vector")
+ checkArg(TRUE, "vector")
+ checkArg("a", "vector")
+ checkArg(list(), "vector")
+ checkArg(list(1), "vector")
+})
+
+
+test_that("checkArg with choices", {
+ f = function(x) checkArg(x, choices=c("a", "b"))
+ f("a")
+ f("b")
+ expect_error(f(c("a", "b")), "must be")
+ expect_error(f(1), "must be")
+ expect_error(f(NULL), "must be")
+ expect_error(f(NA))
+
+ f = function(x) checkArg(x, choices=list(NULL, 1L, data.frame()))
+ f(1L)
+ f(NULL)
+ f(data.frame())
+ expect_error(f(1), "must be")
+ expect_error(f(list(1)), "must be")
+})
+
+
+test_that("checkArg with subset", {
+ f = function(x) checkArg(x, subset=c("a", "b"))
+ f("a")
+ f("b")
+ f(c("a", "b"))
+ f(character(0))
+
+ expect_error(f(1), "must be")
+ expect_error(f(NA), "must be")
+
+ f = function(x) checkArg(x, subset=list(NULL, 1L, data.frame()))
+ f(1L)
+ f(NULL)
+ f(data.frame())
+ f(list(NULL, data.frame()))
+ expect_error(f(1), "must be")
+ expect_error(f(list(1)), "must be")
+})
+
+test_that("checkArg with missing arg", {
+ f = function(x) checkArg(x, "numeric")
+ expect_error(f(), "Argument x must not be missing!")
+})
+
+# FIXME no idea why this does not run in "CMD check"
+if (interactive()) {
+test_that("checkArg with classes / s3 and s4", {
+ x = 1
+ class(x) = c("foo2", "foo1")
+ checkArg(x, "foo1")
+ checkArg(x, "foo1", s4=FALSE)
+ checkArg(x, "foo1", s4=TRUE)
+ checkArg(x, "foo2")
+ checkArg(x, "foo2", s4=FALSE)
+ checkArg(x, "foo2", s4=TRUE)
+ mys41 = setClass("mys41", representation(x="numeric"))
+ mys42 = setClass("mys42", contains="mys41", representation(y="numeric"))
+ obj1 = mys41(x=3)
+ obj2 = mys42(x=3, y=4)
+ checkArg(obj1, "mys41", s4=TRUE)
+ checkArg(obj2, "mys41", s4=TRUE)
+ checkArg(obj2, "mys42", s4=TRUE)
+})
+}
+
+test_that("checkArg with multiple classes", {
+ checkArg(1, c("numeric", "list"))
+ checkArg(1, c("numeric", "foo"))
+ checkArg(1L, c("integer", "list"))
+ checkArg(1L, c("integer", "foo"))
+ checkArg(1L, c("numeric", "list"))
+ checkArg(1L, c("numeric", "foo"))
+})
+
diff --git a/tests/testthat/test_checkListElementClass.R b/tests/testthat/test_checkListElementClass.R
new file mode 100644
index 0000000..29266a0
--- /dev/null
+++ b/tests/testthat/test_checkListElementClass.R
@@ -0,0 +1,12 @@
+context("checkListElementClass")
+
+test_that("checkListElementClass", {
+ checkListElementClass(list(1, 5), cl="numeric")
+ expect_error(checkListElementClass(list(1, "a"), cl="numeric"), "numeric")
+
+ xs = list("a", "b")
+ checkListElementClass(xs, "character")
+ expect_error(checkListElementClass(xs, "integer"), "character")
+})
+
+
diff --git a/tests/testthat/test_chunk.R b/tests/testthat/test_chunk.R
new file mode 100755
index 0000000..663d364
--- /dev/null
+++ b/tests/testthat/test_chunk.R
@@ -0,0 +1,60 @@
+context("chunk")
+
+test_that("chunk", {
+ # normal chunk.size
+ x = 1:9
+ ch = chunk(x, chunk.size=3)
+ expect_equal(ch, list(1:3, 4:6, 7:9))
+
+ # normal n.chunks
+ x = 1:9
+ ch = chunk(x, n.chunks=3)
+ expect_equal(ch, list(1:3, 4:6, 7:9))
+
+ # chunk.size uneven
+ x = 1:10
+ ch = chunk(x, chunk.size=3)
+ expect_equal(ch, list(1:3, 4:6, 7:8, 9:10))
+
+ # n.chunks uneven
+ ch = chunk(1:9, n.chunks=4)
+ expect_equal(length(ch), 4)
+
+ x = letters[1:10]
+ ch = chunk(x, n.chunks = 2)
+ expect_equal(ch, list(letters[1:5], letters[6:10]))
+
+ # errors
+ x = letters[1:10]
+ expect_error(chunk(x, chunk.size=1, n.chunks=3))
+ expect_error(chunk(x, chunk.size=1:2))
+ expect_error(chunk(x, n.chunks=list()))
+
+ x = as.list(letters[1:10])
+ ch = chunk(x, chunk.size=5)
+ expect_equal(ch, list(as.list(letters[1:5]), as.list(letters[6:10])))
+
+ x = letters
+ ch = chunk(x, chunk.size=4, shuffle=TRUE)
+ expect_equal(sort(letters), sort(unlist(ch)))
+ expect_true(all(sapply(ch, length) %in% c(3, 4)))
+
+ # test that smaller levels get chosen randomly
+ x = 1:5
+ counts = sapply(1:100, function(i) {
+ ch = chunk(x, chunk.size=3, shuffle=TRUE)
+ sapply(ch, length) == 2
+ })
+ counts = rowSums(counts)
+ expect_true(all(counts > 30))
+
+ # test proportions
+ x = 1:10
+ ch = chunk(x, props = c(3, 7))
+ expect_equal(sapply(ch, length), c(3, 7))
+ expect_equal(unlist(ch), x)
+
+ expect_true(length(chunk(x, props=1)) == 1L)
+
+})
+
diff --git a/tests/testthat/test_clipString.R b/tests/testthat/test_clipString.R
new file mode 100644
index 0000000..5eb040e
--- /dev/null
+++ b/tests/testthat/test_clipString.R
@@ -0,0 +1,11 @@
+context("clipString")
+
+test_that("clipString", {
+ expect_equal(clipString("abcdef", 7), "abcdef")
+ expect_equal(clipString("abcdef", 6), "abcdef")
+ expect_equal(clipString("abcdef", 5), "ab...")
+ expect_error(clipString("abcdef", 2))
+
+ expect_equal(clipString(NA_character_, 5), NA_character_)
+ expect_equal(clipString(c("aaaaa", NA, "aa"), 4), c("a...", NA, "aa"))
+})
diff --git a/tests/testthat/test_coalesce.R b/tests/testthat/test_coalesce.R
new file mode 100644
index 0000000..066e3f0
--- /dev/null
+++ b/tests/testthat/test_coalesce.R
@@ -0,0 +1,18 @@
+context("coalesce")
+
+test_that("coalesce", {
+ expect_identical(coalesce(NULL), NULL)
+ expect_identical(coalesce(1, NULL), 1)
+ expect_identical(coalesce(NULL, 1), 1)
+ f = function(a, b, c) coalesce(a,b,c)
+ expect_identical(f(b = NULL, c = 1), 1)
+})
+
+test_that("coalesce works with functions", {
+ ff = function(x) 123
+ expect_identical(coalesce(NULL, ff), ff)
+ # FIXME: this is a problem in R / missing. see issue 48
+ #expect_identical(coalesce(NULL, min), min)
+})
+
+
diff --git a/tests/testthat/test_collapse.R b/tests/testthat/test_collapse.R
new file mode 100644
index 0000000..a959c67
--- /dev/null
+++ b/tests/testthat/test_collapse.R
@@ -0,0 +1,7 @@
+context("collapse")
+
+test_that("collapse", {
+ expect_equal(collapse(1), "1")
+ expect_equal(collapse(1:2), "1,2")
+ expect_equal(collapse(c("a", "22")), "a,22")
+})
diff --git a/tests/testthat/test_collapsef.R b/tests/testthat/test_collapsef.R
new file mode 100644
index 0000000..0871e2e
--- /dev/null
+++ b/tests/testthat/test_collapsef.R
@@ -0,0 +1,5 @@
+context("collapsef")
+
+test_that("collapsef", {
+ expect_equal(collapsef("%s=%s", 1:2, 3:4), "1=3,2=4")
+})
diff --git a/tests/testthat/test_computeMode.R b/tests/testthat/test_computeMode.R
new file mode 100644
index 0000000..2494712
--- /dev/null
+++ b/tests/testthat/test_computeMode.R
@@ -0,0 +1,21 @@
+context("computeMode")
+
+test_that("computeMode", {
+ # factor
+ expect_equal(computeMode(as.factor(c(1:2, 2L, 2L))), "2")
+ #character
+ expect_equal(computeMode(c("1","2","3"), ties.method="last"), "3")
+ # numeric
+ expect_equal(computeMode(c(1,1,2,3)), 1)
+ # integer
+ expect_equal(computeMode(c(1:2, 2L, 2L), ties.method="first"), 2L)
+ expect_equal(computeMode(c(1:2, 2L, 2L), ties.method="random"), 2L)
+ expect_equal(computeMode(c(1:2, 2L, 2L), ties.method="last"), 2L)
+ # logical
+ expect_equal(computeMode(c(TRUE, FALSE, FALSE)), FALSE)
+ expect_equal(computeMode(c(TRUE, TRUE, FALSE)), TRUE)
+
+ # na.rm
+ expect_equal(computeMode(c(1,1,2,3, NA, NA, NA), na.rm=FALSE), as.numeric(NA))
+ expect_equal(computeMode(c(1,1,2,3, NA, NA, NA), na.rm=TRUE), 1)
+})
diff --git a/tests/testthat/test_convertDataFrameCols.R b/tests/testthat/test_convertDataFrameCols.R
new file mode 100644
index 0000000..ba2585c
--- /dev/null
+++ b/tests/testthat/test_convertDataFrameCols.R
@@ -0,0 +1,35 @@
+context("convertDataFrameCols")
+
+test_that("convertDataFrameCols", {
+ df = data.frame(x=1:2, y=c("a", "b"), z=factor(c("x", "y")), stringsAsFactors=FALSE)
+ df2 = convertDataFrameCols(df, chars.as.factor=TRUE)
+ expect_true(is.numeric(df2$x))
+ expect_true(is.factor(df2$y))
+ expect_true(is.factor(df2$z))
+ expect_equal(df$x, df2$x)
+ expect_equal(df$y, as.character(df2$y))
+ expect_equal(df$z, df2$z)
+
+ df2 = convertDataFrameCols(df, factors.as.char=TRUE)
+ expect_true(is.numeric(df2$x))
+ expect_true(is.character(df2$y))
+ expect_true(is.character(df2$z))
+ expect_equal(df$x, df2$x)
+ expect_equal(df$y, df2$y)
+ expect_equal(as.character(df$z), df2$z)
+
+ df2 = convertDataFrameCols(df, ints.as.num=TRUE)
+ expect_true(is.double(df2$x))
+ expect_true(is.character(df2$y))
+ expect_true(is.factor(df2$z))
+ expect_equal(df$x, df2$x)
+ expect_equal(df$y, df2$y)
+ expect_equal(df$z, df2$z)
+
+ df2 = convertDataFrameCols(df, chars.as.factor=TRUE, factors.as.char=TRUE, ints.as.num=TRUE)
+ expect_true(is.double(df2$x))
+ expect_true(is.factor(df2$y))
+ expect_true(is.character(df2$z))
+})
+
+
diff --git a/tests/testthat/test_convertInteger.R b/tests/testthat/test_convertInteger.R
new file mode 100644
index 0000000..4458438
--- /dev/null
+++ b/tests/testthat/test_convertInteger.R
@@ -0,0 +1,27 @@
+context("convert ints")
+
+test_that("convertInteger", {
+ expect_true(identical(convertInteger(1), 1L))
+ expect_true(identical(convertInteger(1L), 1L))
+ expect_true(identical(convertInteger(c(1,4)), c(1, 4)))
+ expect_true(identical(convertInteger("a"), "a"))
+ expect_true(identical(convertInteger(NA), as.integer(NA)))
+ expect_true(identical(convertInteger(as.integer(NA)), as.integer(NA)))
+ expect_true(identical(convertInteger(as.numeric(NA)), as.integer(NA)))
+ expect_true(identical(convertInteger(c(1, NA)), c(1, NA)))
+})
+
+
+test_that("convertIntegers", {
+ expect_true(identical(convertIntegers(1), 1L))
+ expect_true(identical(convertIntegers(1L), 1L))
+ expect_true(identical(convertIntegers(c(1,4)), c(1L, 4L)))
+ expect_true(identical(convertIntegers("a"), "a"))
+ expect_true(identical(convertIntegers(NA), as.integer(NA)))
+ expect_true(identical(convertIntegers(c(NA, NA)), as.integer(c(NA, NA))))
+ expect_true(identical(convertIntegers(as.integer(c(NA, NA))), as.integer(c(NA, NA))))
+ expect_true(identical(convertIntegers(as.numeric(c(NA, NA))), as.integer(c(NA, NA))))
+ expect_true(identical(convertIntegers(c(1, NA)), as.integer(c(1, NA))))
+ expect_true(identical(convertIntegers(c()), integer()))
+ expect_true(identical(convertIntegers(c(x = 1, y = 4)), c(x = 1L, y = 4L)))
+})
diff --git a/tests/testthat/test_convertListOfRowsToDataFrame.R b/tests/testthat/test_convertListOfRowsToDataFrame.R
new file mode 100644
index 0000000..5f35bc0
--- /dev/null
+++ b/tests/testthat/test_convertListOfRowsToDataFrame.R
@@ -0,0 +1,43 @@
+context("convertListOfRowstoDataFrame")
+
+test_that("convertListOfRowstoDataFrame", {
+ df1 = convertListOfRowsToDataFrame(list(list(x = 1, y = "a"), list(x = 2, y = "b")),
+ strings.as.factors = FALSE)
+ df2 = data.frame(x = 1:2, y = c("a", "b"), stringsAsFactors = FALSE)
+ expect_equal(df1, df2)
+
+ df1 = convertListOfRowsToDataFrame(list(c(x = "1", y = "a"), list(x = "2", y = "b")),
+ strings.as.factors = FALSE)
+ df2 = data.frame(x=c("1", "2"), y=c("a", "b"), stringsAsFactors = FALSE)
+ expect_equal(df1, df2)
+
+ df1 = convertListOfRowsToDataFrame(list(c("1", "a"), c("2", "b")), strings.as.factors = FALSE,
+ col.names=c("x", "y"))
+ df2 = data.frame(x=c("1", "2"), y=c("a", "b"), stringsAsFactors = FALSE)
+ expect_equal(df1, df2)
+
+ df1 = convertListOfRowsToDataFrame(list(list(a = 1, b = 1), list(b = 12)))
+ df2 = convertListOfRowsToDataFrame(list(c(a = 1, b = 1), c(b = 12)))
+ expect_equal(df1, df2)
+
+ # names
+ df1 = convertListOfRowsToDataFrame(list(list(x = 1, y = "a"), list(x = 2, y = "b")),
+ strings.as.factors = FALSE, row.names = c("r1", "r2"))
+ df2 = setRowNames(data.frame(x = 1:2, y = c("a", "b"), stringsAsFactors = FALSE), c("r1", "r2"))
+ expect_equal(df1, df2)
+
+ df1 = convertListOfRowsToDataFrame(list(list(x = 1, y = "a"), list(x = 2, y = "b")),
+ strings.as.factors = FALSE, row.names = 1:2)
+ df2 = setRowNames(data.frame(x = 1:2, y = c("a", "b"), stringsAsFactors = FALSE), 1:2)
+ expect_equal(df1, df2)
+
+ df1 = convertListOfRowsToDataFrame(list(list(x = 1, y = "a"), list(x = 2, y = "b")),
+ strings.as.factors = FALSE, col.names = c("c1", "c2"))
+ df2 = data.frame(c1 = 1:2, c2 = c("a", "b"), stringsAsFactors = FALSE)
+ expect_equal(df1, df2)
+
+ df1 = convertListOfRowsToDataFrame(list(list(x = 1, y = "a"), list(x = 2, y = "b")),
+ strings.as.factors = FALSE, col.names = 1:2)
+ df2 = setColNames(data.frame(1:2, c("a", "b"), stringsAsFactors = FALSE), 1:2)
+ expect_equal(df1, df2)
+})
diff --git a/tests/testthat/test_convertMatrixType.R b/tests/testthat/test_convertMatrixType.R
new file mode 100644
index 0000000..ce00a71
--- /dev/null
+++ b/tests/testthat/test_convertMatrixType.R
@@ -0,0 +1,7 @@
+context("convertMatrixType")
+
+test_that("convertMatrixType", {
+ a1 = matrix(1:4, 2L, 2L)
+ a2 = matrix(as.character(1:4), 2L, 2L)
+ expect_equal(convertMatrixType(a1, "character"), a2)
+})
diff --git a/tests/testthat/test_convertRowsToList.R b/tests/testthat/test_convertRowsToList.R
new file mode 100644
index 0000000..59fdd9b
--- /dev/null
+++ b/tests/testthat/test_convertRowsToList.R
@@ -0,0 +1,60 @@
+context("convertRowsToList")
+
+test_that("convertRowsToList", {
+ expect_equal(
+ convertRowsToList(matrix(1:4, 2, byrow=TRUE), as.vector = TRUE),
+ list(c(1, 2), c(3, 4))
+ )
+ expect_equal(
+ convertRowsToList(matrix(1:4, 2, byrow=TRUE), as.vector = FALSE),
+ list(list(1, 2), list(3, 4))
+ )
+ expect_equal(
+ convertRowsToList(setColNames(matrix(1:4, 2, byrow = TRUE), c("a", "b")),
+ name.vector = TRUE, as.vector = FALSE),
+ list(list(a=1, b=2), list(a=3, b=4))
+ )
+ expect_equal(
+ convertRowsToList(setColNames(matrix(1:4, 2, byrow = TRUE), c("a", "b")),
+ name.list = FALSE, as.vector = FALSE),
+ list(list(1, 2), list(3, 4))
+ )
+ levs = c("a", "b")
+ expect_equal(
+ convertRowsToList(data.frame(a = 1:2, b = factor(c("a", "b"))),
+ name.list = FALSE, factors.as.char = TRUE),
+ list(list(1, "a"), list(2, "b"))
+ )
+ expect_equal(
+ convertRowsToList(setRowNames(data.frame(a = 1:2, b = factor(c("a", "b"))), c("x", "y")),
+ name.list = TRUE, name.vector = TRUE, factors.as.char = FALSE),
+ list(x = list(a = 1, b = factor("a", levels = levs)), y = list(a = 2, b = factor("b", levels = levs)))
+ )
+})
+
+test_that("convertColsToList", {
+ expect_equal(
+ convertColsToList(matrix(1:4, 2, byrow = FALSE), as.vector = TRUE),
+ list(c(1, 2), c(3, 4))
+ )
+ expect_equal(
+ convertColsToList(matrix(1:4, 2, byrow = FALSE), as.vector = FALSE),
+ list(list(1, 2), list(3, 4))
+ )
+ expect_equal(
+ convertColsToList(setRowNames(matrix(1:4, 2, byrow = FALSE), c("a", "b")),
+ name.vector = TRUE, as.vector = FALSE),
+ list(list(a = 1, b = 2), list(a = 3, b = 4))
+ )
+})
+
+
+test_that("convertColsToList works with data.frame", {
+ d1 = iris
+ x1 = as.list(d1)
+ expect_equal(convertColsToList(d1, factors.as.char = FALSE), x1)
+ d2 = d1; d2$Species = as.character(d2$Species);
+ x2 = as.list(d2)
+ expect_equal(convertColsToList(d1, factors.as.char = TRUE), x2)
+})
+
diff --git a/tests/testthat/test_convertToShortString.R b/tests/testthat/test_convertToShortString.R
new file mode 100644
index 0000000..778433a
--- /dev/null
+++ b/tests/testthat/test_convertToShortString.R
@@ -0,0 +1,27 @@
+context("convertToShortString")
+
+test_that("convertToShortString", {
+ expect_equal(convertToShortString(1L), "1")
+ expect_equal(convertToShortString(1.0), "1")
+ expect_equal(convertToShortString(1.23), "1.23")
+ expect_equal(convertToShortString(numeric(0)), "numeric(0)")
+ expect_equal(convertToShortString(factor(c())), "factor(0)")
+ expect_equal(convertToShortString(iris), "<data.frame>")
+ expect_equal(convertToShortString(list(a=1, 45)), "a=1, <unnamed>=45")
+ expect_equal(convertToShortString(list(a=1, b=list(x=3))), "a=1, b=<list>")
+ expect_equal(convertToShortString(list(a=1, b=iris)), "a=1, b=<data.frame>")
+
+ expect_equal(convertToShortString(list()), "")
+ expect_equal(convertToShortString(list(a=1)), "a=1")
+ expect_equal(convertToShortString(list(a=1:2)), "a=1,2")
+ expect_equal(convertToShortString(list(a=1:20)), "a=1,2,3,4,5,6,...")
+ expect_equal(convertToShortString(list(a=1, 2, b=3)), "a=1, <unnamed>=2, b=3")
+ expect_equal(convertToShortString(list(a=1, 2, b=data.frame())), "a=1, <unnamed>=2, b=<data.frame>")
+ expect_equal(convertToShortString(list(a=identity, b=new.env())), "a=<function>, b=<environment>")
+
+ expect_equal(convertToShortString(list(a=1, b=3.2)), "a=1, b=3.2")
+ expect_equal(convertToShortString(list(a=1, b=3.223), num.format="%.2f"), "a=1.00, b=3.22")
+ expect_equal(convertToShortString(list(a=1L, b=3.223), num.format="%.2f"), "a=1, b=3.22")
+})
+
+
diff --git a/tests/testthat/test_dapply.R b/tests/testthat/test_dapply.R
new file mode 100644
index 0000000..8205c56
--- /dev/null
+++ b/tests/testthat/test_dapply.R
@@ -0,0 +1,20 @@
+context("dapply")
+
+test_that("dapply", {
+ d = dapply(1:3, function(x) rep(x, 2))
+ expect_is(d, "data.frame")
+ expect_equal(dim(d), c(2L, 3L))
+ expect_equal(colnames(d), c("Var.1", "Var.2", "Var.3"))
+
+ d = dapply(1:2, function(x) x, col.names=c("a", "b"))
+ expect_is(d, "data.frame")
+ expect_equal(dim(d), c(1L, 2L))
+ expect_equal(colnames(d), c("a", "b"))
+
+ d1 = dapply(iris, computeMode)
+ d2 = dapply(iris, computeMode, col.names=letters[1:5])
+ expect_equal(dim(d1), c(1L, 5L))
+ expect_equal(dim(d2), c(1L, 5L))
+ expect_equal(names(d1), names(iris))
+ expect_equal(names(d2), letters[1:5])
+})
diff --git a/tests/testthat/test_directory.R b/tests/testthat/test_directory.R
new file mode 100644
index 0000000..63fcdf6
--- /dev/null
+++ b/tests/testthat/test_directory.R
@@ -0,0 +1,22 @@
+context("directory functions")
+
+test_that("isDirectory", {
+ expect_true(isDirectory("."))
+ expect_identical(isDirectory(".", ".."), c(TRUE, TRUE))
+ expect_false(isDirectory("foofoo"))
+ expect_identical(isDirectory(".", "foofoo"), c(TRUE, FALSE))
+})
+
+
+test_that("isEmptyDirectory", {
+ expect_false(isEmptyDirectory("."))
+ td = tempfile()
+ dir.create(td)
+ expect_true(isEmptyDirectory(td))
+ expect_identical(isEmptyDirectory(td, ".."), c(TRUE, FALSE))
+ expect_false(isEmptyDirectory("foofoo"))
+ expect_false(isEmptyDirectory(tempfile()))
+})
+
+
+
diff --git a/tests/testthat/test_do.call2.R b/tests/testthat/test_do.call2.R
new file mode 100644
index 0000000..b2a92eb
--- /dev/null
+++ b/tests/testthat/test_do.call2.R
@@ -0,0 +1,21 @@
+context("do.call2")
+
+test_that("do.call2", {
+ f = function(...) list(...)
+ expect_equal(do.call2("f", a=1, b=2), list(a=1, b=2))
+ expect_equal(do.call2("f", .args=list(a=1, b=2)), list(a=1, b=2))
+ expect_equal(do.call2("f", a=1, .args=list(b=2)), list(a=1, b=2))
+
+ df = iris
+ expect_equal(do.call2("f", df), list(df))
+ expect_equal(do.call2("f", .args = list(df)), list(df))
+
+ f = function(x, data) data[[x]]
+ expect_equal(do.call2("f", "Species", data=iris), iris$Species)
+ expect_equal(do.call2("f", "Species", iris), iris$Species)
+ expect_equal(do.call2("f", data = iris, "Species"), iris$Species)
+ expect_equal(do.call2("f", "Species", .args = list(data = iris)), iris$Species)
+ expect_equal(do.call2("f", data = iris, .args = list(x = "Species")), iris$Species)
+
+ expect_error(do.call2(mean, 1:10), "string")
+})
diff --git a/tests/testthat/test_dropNamed.R b/tests/testthat/test_dropNamed.R
new file mode 100644
index 0000000..dab1c9a
--- /dev/null
+++ b/tests/testthat/test_dropNamed.R
@@ -0,0 +1,36 @@
+context("dropNamed")
+
+test_that("dropNamed", {
+ x = matrix(1:4, 2, 2)
+ colnames(x) = c("a", "b")
+ y = dropNamed(x, character(0))
+ expect_equal(y, x)
+ y = dropNamed(x, c("a"))
+ expect_equal(y, x[, "b", drop=FALSE])
+ y = dropNamed(x, c("a", "b"))
+ expect_equal(y, x[, character(0)])
+
+ x = as.data.frame(x)
+ y = dropNamed(x, character(0))
+ expect_equal(y, x)
+ y = dropNamed(x, c("a"))
+ expect_equal(y, x[, "b", drop=FALSE])
+ y = dropNamed(x, c("a", "b"))
+ expect_equal(y, x[, character(0)])
+
+ x = list(a=1, b=2)
+ y = dropNamed(x, character(0))
+ expect_equal(y, x)
+ y = dropNamed(x, c("a"))
+ expect_equal(y, x["b"])
+ y = dropNamed(x, c("a", "b"))
+ expect_equal(y, x[character(0)])
+
+ x = c(a=1, b=2)
+ y = dropNamed(x, character(0))
+ expect_equal(y, x)
+ y = dropNamed(x, c("a"))
+ expect_equal(y, x["b"])
+ y = dropNamed(x, c("a", "b"))
+ expect_equal(y, x[character(0)])
+})
diff --git a/tests/testthat/test_ensureVector.R b/tests/testthat/test_ensureVector.R
new file mode 100644
index 0000000..3327de2
--- /dev/null
+++ b/tests/testthat/test_ensureVector.R
@@ -0,0 +1,16 @@
+context("ensureVector")
+
+test_that("ensureVector", {
+ expect_equal(ensureVector("a", n = 2L), c("a", "a"))
+ expect_equal(ensureVector("a", n = 2L, cl = "integer"), "a")
+ expect_equal(ensureVector(1, n = 1), c(1))
+
+ expect_equal(ensureVector(c("a", "b"), n = 10L), c("a", "b"))
+
+ expect_equal(ensureVector(iris, n = 1L), list(iris))
+ expect_equal(ensureVector(iris, n = 2L, cl = "matrix"), iris)
+ expect_equal(ensureVector(iris, n = 2L, cl = "data.frame"), list(iris, iris))
+ expect_equal(ensureVector(iris, n = 2L), list(iris, iris))
+ expect_equal(ensureVector(iris, n = 2L, names = c("a", "b")), list(a = iris, b = iris))
+})
+
diff --git a/tests/testthat/test_explode.R b/tests/testthat/test_explode.R
new file mode 100644
index 0000000..45e76ef
--- /dev/null
+++ b/tests/testthat/test_explode.R
@@ -0,0 +1,18 @@
+context("explode")
+
+test_that("explode", {
+ x = "R is a nice programming language"
+ substrings = c("R", "is", "a", "nice", "programming", "language")
+ sep = " "
+
+ # split string
+ exploded = explode(x, sep = sep)
+ expect_equal(length(exploded), 6)
+ for (i in 1:length(substrings)) {
+ expect_equal(substrings[i], exploded[[i]])
+ }
+
+ # now glue the substrings together
+ collapsed = collapse(exploded, sep = sep)
+ expect_equal(collapsed, x)
+})
diff --git a/tests/testthat/test_extractSubList.R b/tests/testthat/test_extractSubList.R
new file mode 100644
index 0000000..948729c
--- /dev/null
+++ b/tests/testthat/test_extractSubList.R
@@ -0,0 +1,64 @@
+context("extractSubList")
+
+test_that("extractSubList", {
+ xs = list(
+ a = list(x = 1, y = "foo", z = matrix(1,1,1)),
+ b = list(x = 2L, y = "bar", z = matrix(2,2,2))
+ )
+ expect_equal(extractSubList(xs, "x"), c(a = 1, b = 2))
+ expect_equal(extractSubList(xs, "y"), c(a = "foo", b = "bar"))
+ expect_equal(extractSubList(xs, "z"), list(a = matrix(1,1,1), b = matrix(2,2,2)))
+
+ expect_equal(extractSubList(xs, "x", use.names = FALSE), c(1, 2))
+ expect_equal(extractSubList(xs, "y", use.names = FALSE), c("foo", "bar"))
+ expect_equal(extractSubList(xs, "z", use.names = FALSE), list(matrix(1,1,1), matrix(2,2,2)))
+
+ expect_equal(extractSubList(list(), "x"), list())
+
+ expect_equal(extractSubList(list(), "x", element.value = numeric(1)), numeric(0))
+ expect_equal(extractSubList(list(), "y", element.value = character(1)), character(0))
+
+ expect_equal(extractSubList(xs, "x", element.value = numeric(1)), c(a = 1, b = 2))
+ expect_equal(extractSubList(xs, "y", element.value = character(1)), c(a = "foo", b = "bar"))
+
+ xs = list(
+ list(x = 1, y = "foo", z = matrix(1,1,1)),
+ list(x = 2L, y = "bar", z = matrix(2,2,2))
+ )
+ expect_equal(extractSubList(xs, "y", use.names = TRUE), c("foo", "bar"))
+ expect_equal(extractSubList(xs, "y", use.names = FALSE), c("foo", "bar"))
+
+ expect_equal(
+ extractSubList(list(list(a = 1:2), list(a = 3:4)), "a", simplify = "rows"),
+ matrix(1:4, nrow = 2L, ncol = 2L, byrow = TRUE)
+ )
+
+ expect_equal(
+ extractSubList(list(list(a = 1), list(a = 2)), "a", simplify = "rows"),
+ matrix(1:2, nrow = 2L, ncol = 1)
+ )
+})
+
+
+
+
+test_that("extractSubList works with repeated indexing", {
+ xs = list(
+ a = list(v = list(x = 1), w = list(y = "foo")),
+ b = list(v = list(x = 2), w = list(y = "bar"))
+ )
+ expect_equal(extractSubList(xs, c("v", "x")), c(a = 1, b = 2))
+ expect_equal(extractSubList(xs, c("w", "y")), c(a = "foo", b = "bar"))
+
+ expect_equal(extractSubList(xs, c("v", "x"), element.value = numeric(1)), c(a = 1, b = 2))
+ expect_equal(extractSubList(xs, c("w", "y"), element.value = character(1)), c(a = "foo", b = "bar"))
+
+
+ expect_equal(extractSubList(xs, c("v", "x"), simplify = "rows", use.names = FALSE), matrix(c(1, 2), nrow = 2))
+ expect_equal(extractSubList(xs, c("v", "x"), simplify = "cols", use.names = TRUE),
+ setColNames(matrix(c(1, 2), nrow = 1), c("a", "b")))
+})
+
+
+
+
diff --git a/tests/testthat/test_factor.R b/tests/testthat/test_factor.R
new file mode 100644
index 0000000..b8d1b0a
--- /dev/null
+++ b/tests/testthat/test_factor.R
@@ -0,0 +1,7 @@
+context("factor")
+
+test_that("combine", {
+ x = factor(c("a", "b"))
+ y = factor(c("b", "c"))
+ expect_equal(cFactor(x,y), factor(c("a", "b", "b", "c")))
+})
\ No newline at end of file
diff --git a/tests/testthat/test_filterNull.R b/tests/testthat/test_filterNull.R
new file mode 100644
index 0000000..e96bc03
--- /dev/null
+++ b/tests/testthat/test_filterNull.R
@@ -0,0 +1,8 @@
+context("filterNull")
+
+test_that("filterNull", {
+ li = list(1, 2, NULL, 3)
+ expect_equal(filterNull(li), list(1, 2, 3))
+ expect_equal(filterNull(list()), list())
+ expect_error(filterNull(iris))
+})
diff --git a/tests/testthat/test_getAttributeNames.R b/tests/testthat/test_getAttributeNames.R
new file mode 100644
index 0000000..1c7b10c
--- /dev/null
+++ b/tests/testthat/test_getAttributeNames.R
@@ -0,0 +1,10 @@
+context("getAttributeNames")
+
+test_that("getAttributeNames", {
+ x = 1:10
+ expect_true(is.null(getAttributeNames(x)))
+
+ attr(x, "size") = length(x)
+ expect_equal(getAttributeNames(x), c("size"))
+})
+
diff --git a/tests/testthat/test_getClass1.R b/tests/testthat/test_getClass1.R
new file mode 100644
index 0000000..0a33cb9
--- /dev/null
+++ b/tests/testthat/test_getClass1.R
@@ -0,0 +1,11 @@
+context("getClass1")
+
+test_that("getClass1", {
+ expect_equal(getClass1(iris), "data.frame")
+ expect_equal(getClass1(1), "numeric")
+ expect_equal(getClass1(NULL), "NULL")
+ x = makeS3Obj(c("C1", "C2"), foo = 2)
+ expect_equal(getClass1(x), "C1")
+})
+
+
diff --git a/tests/testthat/test_getFirstLast.R b/tests/testthat/test_getFirstLast.R
new file mode 100644
index 0000000..72dbfa1
--- /dev/null
+++ b/tests/testthat/test_getFirstLast.R
@@ -0,0 +1,14 @@
+context("getFirstLast")
+
+test_that("getFirstLast", {
+ expect_equal(getFirst(1:3), 1L)
+ expect_equal(getLast(1:3), 3L)
+ expect_equal(getFirst(list(iris, 1)), iris)
+ expect_equal(getLast(list(iris, 1)), 1)
+
+ expect_equal(getFirst(c(a=1, 2)), 1)
+ expect_equal(names(getFirst(c(a=1, 2))), NULL)
+ expect_equal(getLast(c(a=1, 2)), 2)
+ expect_equal(names(getLast(c(a=1, 2))), NULL)
+})
+
diff --git a/tests/testthat/test_getMaxColRowIndex.R b/tests/testthat/test_getMaxColRowIndex.R
new file mode 100644
index 0000000..9517246
--- /dev/null
+++ b/tests/testthat/test_getMaxColRowIndex.R
@@ -0,0 +1,72 @@
+context("getMaxIndexOfRows")
+
+test_that("getMaxIndexOfRows", {
+ a = matrix(1:6, nrow=2)
+ expect_equal(getMaxIndexOfRows(a), c(3L, 3L))
+ a = matrix(6:1, nrow=2)
+ expect_equal(getMaxIndexOfRows(a), c(1L, 1L))
+ a = rbind(c(1, 999), c(-1, -5))
+ expect_equal(getMaxIndexOfRows(a), c(2L, 1L))
+ a = matrix(rnorm(50*10), nrow=50)
+ expect_equal(getMaxIndexOfRows(a), apply(a, 1, which.max))
+})
+
+test_that("getMaxIndexOfCols", {
+ a = matrix(1:6, nrow=2)
+ expect_equal(getMaxIndexOfCols(a), c(2L, 2L, 2L))
+ a = matrix(6:1, nrow=2)
+ expect_equal(getMaxIndexOfCols(a), c(1L, 1L, 1L))
+ a = rbind(c(1, 999), c(-1, -5))
+ expect_equal(getMaxIndexOfCols(a), c(1L, 1L))
+ a = matrix(rnorm(50*10), nrow=50)
+ expect_equal(getMaxIndexOfCols(a), apply(a, 2, which.max))
+})
+
+test_that("normal", {
+ expect_equal(getMaxIndexOfRows(diag(10)), 1:10)
+ n = 100
+ perm = sample(n)
+ D = diag(n)
+ expect_equal(getMaxIndexOfRows(D[perm, ]), (1:n)[perm])
+})
+
+test_that("NA values", {
+ n = 300
+ m = matrix(runif(n), ncol=3)
+ mm = m
+ mm[, 2] = NA
+ expect_equal(getMaxIndexOfRows(mm), rep(NA_integer_, n/3))
+
+ a = matrix(c(1, NA, 2, 3, NA, NA), nrow=3, byrow=TRUE)
+ expect_equal(getMaxIndexOfRows(a, na.rm=FALSE), c(NA, 2L, NA))
+ expect_equal(getMaxIndexOfRows(a, na.rm=TRUE), c(1L, 2L, -1))
+})
+
+test_that("infinite values", {
+ n = 300
+ m = matrix(runif(n), ncol=3)
+ m[, 2] = Inf
+ expect_equal(getMaxIndexOfRows(m), rep(2L, 100L))
+})
+
+test_that("max.col oddity", {
+ expect_equal(getMaxIndexOfRows(cbind(1:10, 2:11, -Inf)), rep(2, 10))
+ expect_equal(getMaxIndexOfRows(cbind(-1e9 * 1:10, 1:10, 2:11)), rep(3, 10))
+})
+
+test_that("ties", {
+ a = matrix(c(1, 1, 2, 2), nrow=2, byrow=TRUE)
+ expect_equal(getMaxIndexOfRows(a, ties.method="first"), c(1L, 1L))
+ expect_equal(getMaxIndexOfRows(a, ties.method="last"), c(2L, 2L))
+ a = matrix(c(2, 1, 2, 2, 2, 1), nrow=2, byrow=TRUE)
+ expect_equal(getMaxIndexOfRows(a, ties.method="first"), c(1L, 1L))
+ expect_equal(getMaxIndexOfRows(a, ties.method="last"), c(3L, 2L))
+ a = matrix(c(1, 1, 2, 2), nrow=2, byrow=TRUE)
+ expect_equal(getMaxIndexOfCols(a, ties.method="first"), c(2L, 2L))
+ expect_equal(getMaxIndexOfCols(a, ties.method="last"), c(2L, 2L))
+ a = matrix(c(2, 1, 2, 2, 2, 1), nrow=2, byrow=TRUE)
+ expect_equal(getMaxIndexOfCols(a, ties.method="first"), c(1L, 2L, 1L))
+ expect_equal(getMaxIndexOfCols(a, ties.method="last"), c(2L, 2L, 1L))
+})
+
+
diff --git a/tests/testthat/test_getMaxIndex.R b/tests/testthat/test_getMaxIndex.R
new file mode 100644
index 0000000..2259a66
--- /dev/null
+++ b/tests/testthat/test_getMaxIndex.R
@@ -0,0 +1,42 @@
+context("getMaxIndex")
+
+test_that("getMaxIndex", {
+ expect_equal(getMaxIndex(c(1, 9)), 2L)
+ expect_equal(getMaxIndex(c(9, 1)), 1L)
+ expect_equal(getMaxIndex(c(-9, -1)), 2L)
+ expect_equal(getMaxIndex(c(-9, 1)), 2L)
+ expect_equal(getMaxIndex(c(1, Inf, 9)), 2L)
+ expect_equal(getMaxIndex(c(1, NA, 9)), NA_integer_)
+ expect_equal(getMaxIndex(c(1, NaN, 9)), NA_integer_)
+ expect_equal(getMaxIndex(c(1, NA, 9), na.rm=TRUE), 3L)
+ expect_equal(getMaxIndex(c(1, NaN, 9), na.rm=TRUE), 3L)
+ expect_equal(getMaxIndex(numeric(0)), integer(0))
+ expect_equal(getMaxIndex(c()), integer(0))
+ expect_equal(getMaxIndex(c(NA, NaN), na.rm=TRUE), integer(0))
+})
+
+test_that("getMinIndex", {
+ expect_equal(getMinIndex(c(1, 9)), 1L)
+ expect_equal(getMinIndex(c(9, 1)), 2L)
+ expect_equal(getMinIndex(c(-9, -1)), 1L)
+ expect_equal(getMinIndex(c(-9, 1)), 1L)
+ expect_equal(getMinIndex(c(1, Inf, 9)), 1L)
+ expect_equal(getMinIndex(c(1, NA, 9)), NA_integer_)
+ expect_equal(getMinIndex(c(1, NaN, 9)), NA_integer_)
+ expect_equal(getMinIndex(c(1, NA, 9), na.rm=TRUE), 1L)
+ expect_equal(getMinIndex(c(1, NaN, 9), na.rm=TRUE), 1L)
+ expect_equal(getMinIndex(numeric(0)), integer(0))
+ expect_equal(getMinIndex(c()), integer(0))
+ expect_equal(getMinIndex(c(NA, NaN), na.rm=TRUE), integer(0))
+})
+
+
+test_that("ties", {
+ expect_equal(getMaxIndex(c(1, 9, 9), ties.method="first"), 2L)
+ expect_equal(getMaxIndex(c(1, 9, 9), ties.method="last"), 3L)
+ expect_equal(getMaxIndex(3, ties.method="first"), 1L)
+ expect_equal(getMaxIndex(3, ties.method="last"), 1L)
+ expect_equal(getMaxIndex(c(9, 1, 9, 9), ties.method="first"), 1L)
+ expect_equal(getMaxIndex(c(9, 1, 9, 9), ties.method="last"), 4L)
+
+})
\ No newline at end of file
diff --git a/tests/testthat/test_getOperatingSystem.R b/tests/testthat/test_getOperatingSystem.R
new file mode 100644
index 0000000..93c845d
--- /dev/null
+++ b/tests/testthat/test_getOperatingSystem.R
@@ -0,0 +1,10 @@
+context("getOperatingSystem")
+
+test_that("getOperatingSystem", {
+ x = getOperatingSystem()
+ expect_true(is.character(x) && length(x) == 1 && nchar(x) > 0)
+ x = isWindows()
+ expect_true(is.logical(x) && length(x) == 1 && !is.na(x))
+ x = isUnix()
+ expect_true(is.logical(x) && length(x) == 1 && !is.na(x))
+})
\ No newline at end of file
diff --git a/tests/testthat/test_getRelativePath.R b/tests/testthat/test_getRelativePath.R
new file mode 100644
index 0000000..e15eb38
--- /dev/null
+++ b/tests/testthat/test_getRelativePath.R
@@ -0,0 +1,21 @@
+context("getRelativePath")
+
+test_that("getRelativePath", {
+ base = tempfile("")
+ a = file.path(base, "foo")
+ b = file.path(base, "bar")
+ c = file.path(base, "bar", "foobar")
+ lapply(c(a, b, c), dir.create, recursive = TRUE)
+
+ expect_equal(getRelativePath(a, from = base), "foo")
+ expect_equal(getRelativePath(b, from = base), "bar")
+ expect_equal(getRelativePath(base, from = a), "..")
+ expect_equal(getRelativePath(base, from = b), "..")
+ expect_equal(getRelativePath(a, from = b), file.path("..", "foo"))
+ expect_equal(getRelativePath(b, from = a), file.path("..", "bar"))
+ expect_equal(getRelativePath(base, from = c), file.path("..", ".."))
+ expect_equal(getRelativePath(c, from = base), file.path("bar", "foobar"))
+ expect_equal(getRelativePath(c, from = a), file.path("..", "bar", "foobar"))
+ if (!isWindows())
+ expect_equal(getRelativePath("/", from = a), do.call(file.path, as.list(rep("..", length(splitPath(a)$path)))))
+})
diff --git a/tests/testthat/test_getUnixTime.R b/tests/testthat/test_getUnixTime.R
new file mode 100644
index 0000000..dafe712
--- /dev/null
+++ b/tests/testthat/test_getUnixTime.R
@@ -0,0 +1,6 @@
+context("getUnixTime")
+
+test_that("getUnixTime", {
+ x = getUnixTime()
+ expect_true(is.integer(x) && length(x) == 1 && !is.na(x))
+})
diff --git a/tests/testthat/test_getUsedFactorLevels.R b/tests/testthat/test_getUsedFactorLevels.R
new file mode 100644
index 0000000..7f337ff
--- /dev/null
+++ b/tests/testthat/test_getUsedFactorLevels.R
@@ -0,0 +1,11 @@
+context("getUsedFactorLevels")
+
+test_that("getUsedFactorLevels", {
+ used.levels = letters[1:3]
+ all.levels = letters
+ x = factor(x = used.levels, levels = all.levels)
+ expect_equal(sort(getUsedFactorLevels(x)), used.levels)
+
+ x = factor(x = used.levels)
+ expect_equal(used.levels, levels(x))
+})
diff --git a/tests/testthat/test_hasAttributes.R b/tests/testthat/test_hasAttributes.R
new file mode 100644
index 0000000..90af264
--- /dev/null
+++ b/tests/testthat/test_hasAttributes.R
@@ -0,0 +1,14 @@
+context("hasAttributes")
+
+test_that("hasAttributes", {
+ x = 1:10
+ attribute.names = c("size", "importance")
+
+ expect_false(hasAttributes(x, attribute.names))
+
+ attr(x, "size") = length(x)
+ expect_false(hasAttributes(x, attribute.names))
+
+ attr(x, "importance") = "very important"
+ expect_true(hasAttributes(x, attribute.names))
+})
diff --git a/tests/testthat/test_insert.R b/tests/testthat/test_insert.R
new file mode 100644
index 0000000..4e091b3
--- /dev/null
+++ b/tests/testthat/test_insert.R
@@ -0,0 +1,13 @@
+context("insert")
+
+test_that("insert", {
+ # list
+ xs1 = list(a=1, b=2)
+ expect_equal(insert(xs1, list(a=99, c=5)), list(a=99, b=2, c=5))
+ expect_equal(insert(xs1, list(a=list(99), c=5)), list(a=list(99), b=2, c=5))
+ # vector
+ xs1 = c(a=1, b=2)
+ expect_equal(insert(xs1, c(a=99, c=5)), c(a=99, b=2, c=5))
+ expect_equal(insert(xs1, c()), xs1)
+})
+
diff --git a/tests/testthat/test_is.subsetsuperset.R b/tests/testthat/test_is.subsetsuperset.R
new file mode 100644
index 0000000..c098963
--- /dev/null
+++ b/tests/testthat/test_is.subsetsuperset.R
@@ -0,0 +1,15 @@
+context("isSubset (and isSuperset)")
+
+test_that("isSubset/isSuperset", {
+ x = 1:10
+ y = 1:11
+ expect_true(isSubset(x, y))
+ expect_false(isSubset(y, x))
+ expect_true(isSubset(x, y, strict = TRUE))
+
+ x = y
+ expect_true(isSubset(x, y))
+ expect_false(isSubset(x, y, strict = TRUE))
+ expect_true(isSubset(y, x))
+ expect_false(isSubset(y, x, strict = TRUE))
+})
diff --git a/tests/testthat/test_isFALSE.R b/tests/testthat/test_isFALSE.R
new file mode 100644
index 0000000..ea56cd1
--- /dev/null
+++ b/tests/testthat/test_isFALSE.R
@@ -0,0 +1,7 @@
+context("isFALSE")
+
+test_that("isFALSE", {
+ expect_equal(isFALSE(FALSE), TRUE)
+ expect_equal(isFALSE(TRUE), FALSE)
+ expect_equal(isFALSE(0), FALSE)
+})
diff --git a/tests/testthat/test_isProperlyNamed.R b/tests/testthat/test_isProperlyNamed.R
new file mode 100644
index 0000000..68c3900
--- /dev/null
+++ b/tests/testthat/test_isProperlyNamed.R
@@ -0,0 +1,13 @@
+context("isProperlyNamed")
+
+test_that("isProperlyNamed", {
+ expect_true(isProperlyNamed(list()))
+ expect_true(isProperlyNamed(list(x=1)))
+ expect_true(isProperlyNamed(list(x=1, y=2)))
+ expect_true(!isProperlyNamed(list(1,2)))
+ xs = list(1,2)
+ names(xs)[1] = "a"
+ expect_true(!isProperlyNamed(xs))
+ names(xs)[2] = "b"
+ expect_true(isProperlyNamed(xs))
+})
\ No newline at end of file
diff --git a/tests/testthat/test_isScalarNA.R b/tests/testthat/test_isScalarNA.R
new file mode 100644
index 0000000..d1ebcaa
--- /dev/null
+++ b/tests/testthat/test_isScalarNA.R
@@ -0,0 +1,9 @@
+context("isScalarNA")
+
+test_that("isScalarNA", {
+ expect_true(isScalarNA(NA))
+ expect_false(isScalarNA(1))
+ expect_false(isScalarNA(iris))
+ expect_false(isScalarNA(NULL))
+ expect_false(isScalarNA("NA"))
+})
\ No newline at end of file
diff --git a/tests/testthat/test_isScalarValue.R b/tests/testthat/test_isScalarValue.R
new file mode 100644
index 0000000..fad0d23
--- /dev/null
+++ b/tests/testthat/test_isScalarValue.R
@@ -0,0 +1,32 @@
+context("isScalarValue")
+
+test_that("isScalarValue", {
+ expect_true(isScalarValue(1))
+ expect_true(isScalarValue(1L))
+ expect_true(isScalarValue("a"))
+ expect_true(isScalarValue(factor("a")))
+ expect_true(isScalarValue(as.complex(1)))
+ expect_true(isScalarValue(NA))
+
+ expect_true(isScalarNumeric(1))
+ expect_true(isScalarInteger(1L))
+ expect_true(isScalarCharacter("a"))
+ expect_true(isScalarFactor(factor("a")))
+ expect_true(isScalarComplex(as.complex(1)))
+ expect_true(isScalarLogical(NA))
+
+ expect_false(isScalarComplex(1L))
+ expect_false(isScalarInteger(1))
+ expect_false(isScalarFactor("a"))
+ expect_false(isScalarCharacter(factor("a")))
+ expect_false(isScalarNumeric(as.complex(1)))
+ expect_false(isScalarInteger(NA))
+
+ expect_false(isScalarValue(NULL))
+ expect_false(isScalarValue(iris))
+ expect_false(isScalarValue(1:2))
+ expect_false(isScalarValue(list(1)))
+
+ expect_true(isScalarValue(NULL, null.ok=TRUE))
+ expect_false(isScalarValue(NULL, na.ok=FALSE))
+})
diff --git a/tests/testthat/test_isValidNames.R b/tests/testthat/test_isValidNames.R
new file mode 100644
index 0000000..4f51cd8
--- /dev/null
+++ b/tests/testthat/test_isValidNames.R
@@ -0,0 +1,9 @@
+context("isValidName")
+
+test_that("isValidName", {
+ expect_true(isValidName("a"))
+ expect_true(all(isValidName(c("a", "b"))))
+ expect_equal(isValidName(c("a", "a")), c(TRUE, FALSE))
+ expect_true(all(isValidName(c("a", "a"), unique=FALSE)))
+ expect_equal(isValidName(c("x", "..1")), c(TRUE, FALSE))
+})
diff --git a/tests/testthat/test_is_error.R b/tests/testthat/test_is_error.R
new file mode 100644
index 0000000..d9b479a
--- /dev/null
+++ b/tests/testthat/test_is_error.R
@@ -0,0 +1,6 @@
+context("is.error")
+
+test_that("is.error", {
+ expect_true(is.error(try(stop("foo"), silent=TRUE)))
+ expect_false(is.error(try("foo")))
+})
diff --git a/tests/testthat/test_itostr.R b/tests/testthat/test_itostr.R
new file mode 100644
index 0000000..d2e3e68
--- /dev/null
+++ b/tests/testthat/test_itostr.R
@@ -0,0 +1,17 @@
+context("itostr")
+
+test_that("itostr", {
+ x = 0:200
+ base = c(2, 10, 16, 24, 32, 36)
+
+ for (b in base) {
+ res = itostr(x, b)
+ expect_true(is.character(res))
+ expect_true(length(x) == length(res))
+ expect_equal(strtoi(res, b), x)
+ }
+
+ expect_error(itostr(1, 0))
+ expect_error(itostr(1, 1))
+ expect_error(itostr(-1, 2))
+})
diff --git a/tests/testthat/test_load2_save2.R b/tests/testthat/test_load2_save2.R
new file mode 100644
index 0000000..4b08d47
--- /dev/null
+++ b/tests/testthat/test_load2_save2.R
@@ -0,0 +1,26 @@
+context("load2")
+
+test_that("load2", {
+ fd = tempdir()
+ fn = file.path(fd, "foo.RData")
+ save2(file=fn, x=1)
+ expect_equal(load2(fn), 1)
+ expect_equal(load2(fn, parts="x"), 1)
+ z = list(x=1)
+ expect_equal(load2(fn, simplify=FALSE), z)
+ expect_error(load2(fn, parts="y"), "does not contain: y")
+ ee = new.env()
+ load2(fn, envir=ee)
+ expect_equal(ee$x, 1)
+
+ fn2 = file.path(fd, "xxx.RData")
+ expect_error(expect_warning(load2(fn2)))
+ expect_equal(load2(fn2, impute = NA), NA)
+
+ save2(file=fn, x=1, y=2)
+ z = list(x=1, y=2)
+ expect_equal(load2(fn), z)
+ expect_equal(load2(fn, parts=c("x", "y")), z)
+ expect_equal(load2(fn, parts="x"), 1)
+ expect_equal(load2(fn, parts="y"), 2)
+})
diff --git a/tests/testthat/test_lsort.R b/tests/testthat/test_lsort.R
new file mode 100644
index 0000000..71abc96
--- /dev/null
+++ b/tests/testthat/test_lsort.R
@@ -0,0 +1,6 @@
+context("lsort")
+
+test_that("lsort", {
+ expect_equal(lsort(c("c", "a", "b")), c("a", "b", "c"))
+ expect_equal(lsort( c("a", "ä", "ö", "o")), c("a", "o", "ä", "ö"))
+})
diff --git a/tests/testthat/test_makeDataFrame.R b/tests/testthat/test_makeDataFrame.R
new file mode 100644
index 0000000..2bd1d34
--- /dev/null
+++ b/tests/testthat/test_makeDataFrame.R
@@ -0,0 +1,36 @@
+context("makeDataFrame")
+
+test_that("makeDataFrame", {
+ df1 = makeDataFrame(0, 0)
+ df2 = data.frame()
+ expect_equal(df1, df2)
+ df1 = makeDataFrame(3, 0)
+ df2 = data.frame(matrix(nrow = 3, ncol = 0))
+ expect_equal(df1, df2)
+ df1 = makeDataFrame(0, 2, "character")
+ df2 = data.frame(setColNames(matrix("a", nrow = 0, ncol = 2), c("V1", "V2")), stringsAsFactors = FALSE)
+ expect_equal(df1, df2)
+ df1 = makeDataFrame(3, 1, "integer")
+ df2 = data.frame(V1 = integer(3))
+ expect_equal(df1, df2)
+ df1 = makeDataFrame(3, 2, "integer")
+ df2 = as.data.frame(matrix(0L, 3, 2))
+ expect_equal(df1, df2)
+ df1 = makeDataFrame(3, 2, init = "bb")
+ df2 = as.data.frame(matrix("bb", 3, 2), stringsAsFactors = FALSE)
+ expect_equal(df1, df2)
+ df1 = makeDataFrame(3, 2, c("numeric", "integer"))
+ df2 = data.frame(V1 = numeric(3), V2 = integer(3), stringsAsFactors = FALSE)
+ expect_equal(df1, df2)
+
+ # names
+ df1 = makeDataFrame(1, 2, "integer", row.names = c("r1"), col.names = c("c1", "c2"))
+ df2 = setRowNames(data.frame(c1 = 0, c2 = 0), "r1")
+ expect_equal(df1, df2)
+ df1 = makeDataFrame(1, 2, "integer", row.names = 1L, col.names = c("c1", "c2"))
+ df2 = setRowNames(data.frame(c1 = 0, c2 = 0), 1L)
+ expect_equal(df1, df2)
+ df1 = makeDataFrame(1, 2, "integer", row.names = NULL, col.names = 1:2)
+ df2 = setColNames(data.frame(c1 = 0, c2 = 0), 1:2)
+ expect_equal(df1, df2)
+})
diff --git a/tests/testthat/test_makeProgressBar.R b/tests/testthat/test_makeProgressBar.R
new file mode 100644
index 0000000..af81880
--- /dev/null
+++ b/tests/testthat/test_makeProgressBar.R
@@ -0,0 +1,50 @@
+context("makeProgressBar")
+
+test_that("makeProgressBar", {
+ cat("\n")
+ bar = makeProgressBar()
+ for(i in 0:100) {
+ bar$set(i)
+ Sys.sleep(0.01)
+ }
+ bar = makeProgressBar(min=10, max=50, label="foo")
+ for(i in 11:50) {
+ bar$set(i)
+ Sys.sleep(0.01)
+ }
+ bar = makeProgressBar(min=0.1, max=0.2)
+ for(i in seq(0.1, 0.2, length.out=5)) {
+ bar$set(i)
+ Sys.sleep(0.1)
+ }
+ bar$set(0.2)
+ bar$set(0.2)
+ bar = makeProgressBar(max=10^6, label=" ")
+ for(i in 10^seq(1:6)) {
+ bar$set(i, msg=sprintf("%i", i))
+ Sys.sleep(0.1)
+ }
+
+ bar = makeProgressBar(min=0, max=0)
+ bar$set(0)
+ bar = makeProgressBar(min=0, max=0)
+ bar$inc(0)
+})
+
+test_that("makeProgressBar global options", {
+ old.style = getOption("BBmisc.ProgressBar.style")
+ old.width = getOption("BBmisc.ProgressBar.width")
+ options(BBmisc.ProgressBar.style = "off")
+ cat("\n")
+ bar = makeProgressBar(max=5)
+ for(i in 0:5) {
+ expect_silent(bar$set(i))
+ }
+ options(BBmisc.ProgressBar.style = "text", BBmisc.ProgressBar.width = 30)
+ cat("\n")
+ bar = makeProgressBar(max=5)
+ for(i in 0:5) {
+ expect_output(print(bar$set(i)))
+ }
+ options(BBmisc.ProgressBar.style = old.style, BBmisc.ProgressBar.width = old.width)
+})
diff --git a/tests/testthat/test_makeSimpleFileLogger.R b/tests/testthat/test_makeSimpleFileLogger.R
new file mode 100644
index 0000000..46cf9df
--- /dev/null
+++ b/tests/testthat/test_makeSimpleFileLogger.R
@@ -0,0 +1,33 @@
+context("makeSimpleFileLogger")
+
+test_that("makeSimpleFileLogger", {
+ fn = tempfile()
+ logger = makeSimpleFileLogger(fn)
+ expect_identical(class(logger), "SimpleFileLogger")
+
+ expect_equal(logger$getSize(), 0)
+ msg1 = "xxx111xxx"
+ logger$log(msg1)
+ expect_true(grepl(msg1, readLines(fn)))
+ expect_identical(msg1, logger$getMessages(1))
+ expect_equal(logger$getSize(), 1)
+
+ expect_true(file.exists(fn))
+ logger$clear()
+ expect_false(file.exists(fn))
+})
+
+test_that("message order", {
+ fn = tempfile()
+ msg1 = "xxx111xxx"
+ msg2 = "xxx222xxx"
+ for (keep in c(0, 10)) {
+ logger = makeSimpleFileLogger(fn)
+ logger$log(msg1)
+ logger$log(msg2)
+ expect_identical(grepl("xxx[0-9]+xxx$", readLines(fn)), c(TRUE, TRUE))
+ expect_identical(grepl("^xxx[0-9]+xxx$", logger$getMessages(2)), c(TRUE, TRUE))
+ expect_identical(logger$getMessages(1), msg2)
+ expect_identical(logger$getMessages(2), c(msg2, msg1))
+ }
+})
diff --git a/tests/testthat/test_mapValues.R b/tests/testthat/test_mapValues.R
new file mode 100644
index 0000000..807d231
--- /dev/null
+++ b/tests/testthat/test_mapValues.R
@@ -0,0 +1,13 @@
+context("mapValues")
+
+test_that("mapValues", {
+ expect_equal(mapValues(1:3, 2, 3), c(1, 3, 3))
+ expect_equal(mapValues(letters[1:5], letters[1:5], rev(letters[1:5])), rev(letters[1:5]))
+ expect_equal(mapValues(factor(c("a", "b", "c")), "b", "zzz"), factor(c("a", "zzz", "c"), levels = c("a", "zzz", "c")))
+ expect_equal(mapValues(c("aab", "aba", "baa"), "aa", "zz", regex = TRUE), c("zzb", "aba", "bzz"))
+ expect_equal(mapValues(c("aab", "aba", "baa"), "^aa.+", "zz", regex = TRUE), c("zz", "aba", "baa"))
+
+ expect_error(mapValues(iris, 1, 1), "atomic")
+ expect_error(mapValues(1:10, 1:2, 1), "length")
+ expect_error(mapValues(1:10, 1, 1:2), "length")
+})
diff --git a/tests/testthat/test_namedList.R b/tests/testthat/test_namedList.R
new file mode 100644
index 0000000..2cc5c45
--- /dev/null
+++ b/tests/testthat/test_namedList.R
@@ -0,0 +1,10 @@
+context("namedList")
+
+test_that("namedList", {
+ expect_equal(namedList(), vector("list", 0))
+ expect_equal(namedList("a"), list(a=NULL))
+ expect_equal(namedList(c("a", "b")), list(a=NULL, b=NULL))
+ expect_equal(namedList(c("a", "b"), 1), list(a=1, b=1))
+ f = function(x) x^2
+ expect_equal(namedList(c("a", "b"), f(2)), list(a=4, b=4))
+})
diff --git a/tests/testthat/test_nin.R b/tests/testthat/test_nin.R
new file mode 100644
index 0000000..694c986
--- /dev/null
+++ b/tests/testthat/test_nin.R
@@ -0,0 +1,10 @@
+context("nin")
+
+test_that("nin", {
+ expect_true(1 %nin% 2:3)
+ expect_false(1 %nin% 1)
+ expect_false(1 %nin% c(NA, 1))
+ expect_true(1 %nin% c(NA, 2))
+ expect_false(NA %nin% c(NA, 1))
+ expect_true(NA %nin% 1:2)
+})
diff --git a/tests/testthat/test_normalize.R b/tests/testthat/test_normalize.R
new file mode 100644
index 0000000..23859aa
--- /dev/null
+++ b/tests/testthat/test_normalize.R
@@ -0,0 +1,73 @@
+context("normalize")
+
+test_that("normalize", {
+ # vector
+ x = runif(20)
+ y = normalize(x, method = "range")
+ expect_is(y, "numeric")
+ expect_equal(range(y), c(0, 1))
+ y = normalize(x, method = "range", range = c(-4, 2))
+ expect_is(y, "numeric")
+ expect_equal(range(y), c(-4, 2))
+ y = normalize(x, method = "center")
+ expect_is(y, "numeric")
+ expect_equal(mean(y), 0)
+ y = normalize(x, method = "standardize")
+ expect_is(y, "numeric")
+ expect_equal(mean(y), 0)
+ expect_equal(sd(y), 1)
+
+ # matrix
+ x = matrix(runif(100), nrow = 5)
+ y = normalize(x, margin = 1L)
+ expect_is(y, "matrix")
+ apply(y, 1, function(v) expect_equal(mean(v), 0))
+ apply(y, 1, function(v) expect_equal(sd(v), 1))
+ y = normalize(x, margin = 2L)
+ apply(y, 2, function(v) expect_equal(mean(v), 0))
+ apply(y, 2, function(v) expect_equal(sd(v), 1))
+
+ # data.frame
+ y = normalize(iris, method = "range", range = c(3, 4))
+ expect_is(y, "data.frame")
+ for (i in 1:4)
+ expect_equal(range(y[, i]), c(3, 4))
+ expect_equal(y[, 5L], iris$Species)
+
+ # constant vectors
+ x = rep(1, 10)
+ y = normalize(x, method = "center", on.constant = "quiet")
+ expect_is(y, "numeric")
+ expect_equal(y, x - x)
+ y = normalize(x, method = "scale", on.constant = "quiet")
+ expect_is(y, "numeric")
+ expect_equal(y, x)
+ y = normalize(x, method = "standardize", on.constant = "quiet")
+ expect_is(y, "numeric")
+ expect_equal(y, x - x)
+ y = normalize(x, method = "range", on.constant = "quiet", range = c(-3, 2))
+ expect_is(y, "numeric")
+ expect_equal(y, rep(-0.5, 10))
+ expect_error(normalize(x, method = "center", on.constant = "stop"))
+ expect_error(normalize(x, method = "scale", on.constant = "stop"))
+ expect_error(normalize(x, method = "standardize", on.constant = "stop"))
+ expect_error(normalize(x, method = "range", on.constant = "stop"))
+ expect_warning(normalize(x, method = "center", on.constant = "warn"))
+ expect_warning(normalize(x, method = "scale", on.constant = "warn"))
+ expect_warning(normalize(x, method = "standardize", on.constant = "warn"))
+ expect_warning(normalize(x, method = "range", on.constant = "warn"))
+})
+
+test_that("normalize works with NAs", {
+ # vector
+ x = c(1, 2, NA)
+ y = normalize(x, method = "range")
+ expect_equal(y, c(0, 1, NA))
+ y = normalize(x, method = "center")
+ expect_equal(y, c(-0.5, 0.5, NA))
+
+ # matrix
+ x = matrix(c(1, 2, 1, NA), nrow = 2L)
+ y = normalize(x, margin = 2L, method = "range")
+ expect_equal(y, matrix(c(0, 1, 0.5, NA), nrow = 2L))
+})
diff --git a/tests/testthat/test_optimizeSubInts.R b/tests/testthat/test_optimizeSubInts.R
new file mode 100644
index 0000000..2edbaab
--- /dev/null
+++ b/tests/testthat/test_optimizeSubInts.R
@@ -0,0 +1,15 @@
+context("optimizeSubInts")
+
+test_that("optimizeSubInts", {
+
+ f = function(x) sin(x) * x
+ z = optimizeSubInts(f, interval = c(0, 50), nsub = 200L)
+ fopt = f(pi * 3 / 2 + 14 * pi)
+ expect_true(abs(fopt - z$objective) < 1e-1)
+
+ # test with nsub = 1, had a bug here
+ f = function(x) sum(x^2)
+ z = optimizeSubInts(f, interval = c(-10, 10), nsub = 1)
+ expect_true(abs(z$minimum) < 1e-5)
+})
+
diff --git a/tests/testthat/test_printStrToChar.R b/tests/testthat/test_printStrToChar.R
new file mode 100644
index 0000000..724c0b7
--- /dev/null
+++ b/tests/testthat/test_printStrToChar.R
@@ -0,0 +1,11 @@
+context("printStrToChar")
+
+test_that("printStrToChar", {
+ x = 1L
+ s = printStrToChar(x, collapse=NULL)
+ expect_equal(s, " int 1")
+ s = printStrToChar(iris, collapse=NULL)
+ expect_true(is.character(s) && length(s) == 6)
+ s = printStrToChar(iris)
+ expect_true(is.character(s) && length(s) == 1)
+})
\ No newline at end of file
diff --git a/tests/testthat/test_printToChar.R b/tests/testthat/test_printToChar.R
new file mode 100644
index 0000000..fb164c5
--- /dev/null
+++ b/tests/testthat/test_printToChar.R
@@ -0,0 +1,14 @@
+context("printToChar")
+
+test_that("printToChar", {
+ if (!interactive()) {
+ z = list()
+ class(z) = "foo"
+ print.foo <<- function(x, ...) catf("bar")
+ s = printToChar(z)
+ expect_equal(s, "bar")
+ print.foo <<- function(x, ...) catf("bar\nblubb")
+ s = printToChar(z)
+ expect_equal(s, "bar\nblubb")
+ }
+})
\ No newline at end of file
diff --git a/tests/testthat/test_printf.R b/tests/testthat/test_printf.R
new file mode 100644
index 0000000..89214c1
--- /dev/null
+++ b/tests/testthat/test_printf.R
@@ -0,0 +1,37 @@
+context("print*f variants")
+
+test_that("messagef", {
+ expect_message(messagef("xxx%ixxx", 123), "xxx123xxx")
+})
+
+test_that("catf", {
+ expect_output(catf("xxx%ixxx", 123), "xxx123xxx")
+})
+
+test_that("catf into file", {
+ fn = tempfile()
+ catf("xxx%ixxx", 123, file=fn)
+ s = readLines(fn)
+ expect_equal(s, "xxx123xxx")
+ unlink(fn)
+})
+
+
+
+test_that("warningf", {
+ expect_warning(warningf("xxx%ixxx", 123), "xxx123xxx")
+ f = function() warningf("123")
+ # "Warning: " not caught by gives_warning
+ expect_warning(f(), "123")
+})
+
+test_that("stopf", {
+ expect_error(stopf("xxx%ixxx", 123), "xxx123xxx")
+ f = function() stopf("123")
+ # because try is called in throws_error
+ # (and prints a bit differently of course!!!!)
+ # we get an extra space before the :
+ expect_error(f(), "123")
+})
+
+
diff --git a/tests/testthat/test_rangeVal.R b/tests/testthat/test_rangeVal.R
new file mode 100644
index 0000000..d77d7c8
--- /dev/null
+++ b/tests/testthat/test_rangeVal.R
@@ -0,0 +1,13 @@
+
+context("rangeVal")
+
+test_that("rangeVal", {
+ expect_equal(rangeVal(c(1, 5)), 4)
+ expect_equal(rangeVal(1), 0)
+ expect_equal(rangeVal(1:3), 2)
+
+ # NAs
+ expect_equal(rangeVal(c(1, 2, NA)), NA_real_)
+ expect_equal(rangeVal(c(1, 2, NA), na.rm = TRUE), 1)
+ expect_equal(rangeVal(c(NA_real_), na.rm = TRUE), NA_real_)
+})
diff --git a/tests/testthat/test_requirePackages.R b/tests/testthat/test_requirePackages.R
new file mode 100644
index 0000000..53c4e9d
--- /dev/null
+++ b/tests/testthat/test_requirePackages.R
@@ -0,0 +1,28 @@
+context("requirePackages")
+
+test_that("requirePackages", {
+ expect_equal(requirePackages("base"), c(base=TRUE))
+ expect_equal(requirePackages("xxx", stop = FALSE, suppress.warnings = TRUE), c(xxx=FALSE))
+ expect_error(requirePackages("xxx", suppress.warnings=TRUE), "Please install the following packages: xxx")
+ expect_equal(requirePackages(c("xxx", "base"), stop=FALSE, suppress.warnings=TRUE), c(xxx=FALSE, base=TRUE))
+ expect_equal(requirePackages(c("base", "xxx"), stop=FALSE, suppress.warnings=TRUE), c(base=TRUE, xxx=FALSE))
+ expect_error(requirePackages(c("base", "xxx"), suppress.warnings=TRUE), "Please install the following packages: xxx")
+ expect_error(requirePackages(c("base", "xxx"), why="test", suppress.warnings=TRUE), "For test please install the following packages: xxx")
+
+ # test loading vs. attaching using the codetools package
+ expect_equal(requirePackages("codetools", default.method = "load"), c(codetools=TRUE))
+ expect_true("codetools" %in% loadedNamespaces())
+ expect_false("package:codetools" %in% search())
+ expect_equal(requirePackages("!codetools", default.method = "load"), c(codetools=TRUE))
+ expect_true("package:codetools" %in% search())
+})
+
+test_that("requirePackages with min.versions", {
+ expect_equal(requirePackages("base", min.versions = "0.1"), c(base=TRUE))
+ expect_equal(requirePackages("base", min.versions = c(base="0.1")), c(base=TRUE))
+
+ expect_equal(requirePackages(c("base", "stats")), c(base=TRUE, stats = TRUE))
+ expect_equal(requirePackages(c("base", "stats"), min.versions = c(base = "100"), stop = FALSE), c(base=FALSE, stats = TRUE))
+ expect_error(requirePackages(c("base", "stats"), min.versions = c(stats = "100")), "stats >= 100")
+})
+
diff --git a/tests/testthat/test_rowLapply.R b/tests/testthat/test_rowLapply.R
new file mode 100644
index 0000000..5dd4c62
--- /dev/null
+++ b/tests/testthat/test_rowLapply.R
@@ -0,0 +1,33 @@
+context("rowLapply / rowSapply")
+
+test_that("rowLapply", {
+ df = data.frame(a = 1:10, b = 10:1)
+ expect_true(all(rowLapply(df, length, unlist = TRUE) == 2))
+ expect_true(all(rowLapply(df, sum, unlist = TRUE) == 11))
+ expect_true(all(unlist(rowLapply(df, Negate(is.list), unlist = TRUE))))
+ expect_true(all(unlist(rowLapply(df, is.list))))
+ fun = function(x, y) sum(c(unlist(x), y))
+ expect_equal(rowLapply(df[, 1L, drop = FALSE], fun, y = 1), as.list(2:11))
+})
+
+
+test_that("rowSapply", {
+ df = data.frame(a = 1:10, b = 10:1)
+ rownames(df) = letters[1:10]
+ y1 = rep(2, nrow(df))
+ y2 = setNames(y1, rownames(df))
+ expect_equal(rowSapply(df, length, simplify = TRUE, use.names = FALSE), y1)
+ expect_equal(rowSapply(df, length, simplify = TRUE, use.names = TRUE), y2)
+ expect_equal(rowSapply(df, length, simplify = FALSE, use.names = FALSE), as.list(y1))
+ expect_equal(rowSapply(df, length, simplify = FALSE, use.names = TRUE), as.list(y2))
+ x1 = rowSapply(df, unlist, simplify = TRUE, use.names = TRUE)
+ x2 = sapply(1:nrow(df), function(i) unlist(df[i,]), simplify = TRUE, USE.NAMES = FALSE)
+ rownames(x2) = NULL; colnames(x2) = rownames(df)
+ expect_equal(x1, x2)
+ x1 = rowSapply(df, unlist, simplify = "rows", use.names = FALSE)
+ x2 = as.matrix(data.frame(a = 1:10, b = 10:1))
+ expect_equal(x1, x2)
+ x1 = rowSapply(data.frame(a = 1:2), function(r) r$a, simplify = "rows", use.names = FALSE)
+ x2 = matrix(1:2, nrow = 2)
+ expect_equal(x1, x2)
+})
diff --git a/tests/testthat/test_seq.R b/tests/testthat/test_seq.R
new file mode 100644
index 0000000..a9a36c5
--- /dev/null
+++ b/tests/testthat/test_seq.R
@@ -0,0 +1,6 @@
+context("seq")
+
+test_that("seq", {
+ expect_equal(seq_row(iris), seq_len(nrow(iris)))
+ expect_equal(seq_col(iris), seq_len(ncol(iris)))
+})
diff --git a/tests/testthat/test_setAttribute.R b/tests/testthat/test_setAttribute.R
new file mode 100644
index 0000000..9c21ef1
--- /dev/null
+++ b/tests/testthat/test_setAttribute.R
@@ -0,0 +1,10 @@
+context("setAttribute")
+
+test_that("setAttribute", {
+ x = 1:9
+ x = setAttribute(x, "foo", "bar")
+ x = setAttribute(x, "dim", c(3,3))
+ expect_equal(attr(x, "foo"), "bar")
+ expect_equal(nrow(x), 3)
+ expect_equal(ncol(x), 3)
+})
diff --git a/tests/testthat/test_setClasses.R b/tests/testthat/test_setClasses.R
new file mode 100644
index 0000000..54e9800
--- /dev/null
+++ b/tests/testthat/test_setClasses.R
@@ -0,0 +1,7 @@
+context("setClasses")
+
+test_that("setClasses", {
+ x = list(a=1)
+ expect_equal(setClasses(x, "foo"), structure(list(a=1), class="foo"))
+ expect_equal(setClasses(x, c("foo1", "foo2")), structure(list(a=1), class=c("foo1", "foo2")))
+})
diff --git a/tests/testthat/test_setRowColNames.R b/tests/testthat/test_setRowColNames.R
new file mode 100644
index 0000000..c9d3719
--- /dev/null
+++ b/tests/testthat/test_setRowColNames.R
@@ -0,0 +1,9 @@
+context("setRowColNames")
+
+test_that("setRowColNames", {
+ x = y = matrix(1:4, 2, 2)
+ rownames(y) = c("a", "b")
+ expect_equal(setRowNames(x, c("a", "b")), y)
+ colnames(y) = c("c", "d")
+ expect_equal(setColNames(setRowNames(x, c("a", "b")), c("c", "d")), y)
+})
diff --git a/tests/testthat/test_setValue.R b/tests/testthat/test_setValue.R
new file mode 100644
index 0000000..784967b
--- /dev/null
+++ b/tests/testthat/test_setValue.R
@@ -0,0 +1,11 @@
+context("setValue")
+
+test_that("setValue", {
+ xs1 = list(a=1, b=2)
+ expect_equal(setValue(xs1, "b", 3), list(a=1, b=3))
+ expect_equal(setValue(xs1, "b", NULL), list(a=1, b=NULL))
+ expect_equal(setValue(xs1, "c", 3), list(a=1, b=2, c=3))
+ expect_equal(setValue(xs1, c("a","b"), as.list(4:5)), list(a=4, b=5))
+ expect_equal(setValue(xs1, c("b","c"), as.list(4:5)), list(a=1, b=4, c=5))
+})
+
diff --git a/tests/testthat/test_sortByCol.R b/tests/testthat/test_sortByCol.R
new file mode 100644
index 0000000..ba5ac64
--- /dev/null
+++ b/tests/testthat/test_sortByCol.R
@@ -0,0 +1,36 @@
+context("sortByCol")
+
+test_that("sortByCol", {
+ d1 = setRowNames(data.frame(x = c(2, 3, 1), y = c("a", "c", "b")), c("1", "2", "3"))
+
+ d2 = sortByCol(d1, "x")
+ d3 = setRowNames(data.frame(x = c(1, 2, 3), y = c("b", "a", "c")), c(3, 1, 2))
+ expect_equal(d2, d3)
+
+ d2 = sortByCol(d1, "x", asc = FALSE)
+ d3 = setRowNames(data.frame(x = c(3, 2, 1), y = c("c", "a", "b")), c(2, 1, 3))
+ expect_equal(d2, d3)
+
+ d2 = sortByCol(d1, c("x", "y"))
+ d3 = setRowNames(data.frame(x = c(1, 2, 3), y = c("b", "a", "c")), c(3, 1, 2))
+ expect_equal(d2, d3)
+
+ d2 = sortByCol(d1, "y")
+ d3 = setRowNames(data.frame(x = c(2, 1, 3), y = c("a", "b", "c")), c(1, 3, 2))
+ expect_equal(d2, d3)
+
+ # real tie breaker
+ d1 = data.frame(x = c(2, 2, 1), y = c("a", "b", "c"))
+ d2 = sortByCol(d1, c("x", "y"))
+ d3 = data.frame(x = c(1, 2, 2), y = c("c", "a", "b"))
+ expect_equal(d2, d3, check.attributes = FALSE)
+ d2 = sortByCol(d1, c("x", "y"), asc = c(TRUE, FALSE))
+ d3 = data.frame(x = c(1, 2, 2), y = c("c", "b", "a"))
+ expect_equal(d2, d3, check.attributes = FALSE)
+
+ # one col
+ d1 = setRowNames(data.frame(x = c(1, 2)), c(1, 2))
+ d2 = sortByCol(d1, "x", asc = FALSE)
+ d3 = setRowNames(data.frame(x = c(2, 1)), c(2, 1))
+ expect_equal(d2, d3)
+})
diff --git a/tests/testthat/test_splitPath.R b/tests/testthat/test_splitPath.R
new file mode 100644
index 0000000..bcd39fd
--- /dev/null
+++ b/tests/testthat/test_splitPath.R
@@ -0,0 +1,17 @@
+context("splitPath")
+
+test_that("splitPath", {
+ p = tempfile()
+ res = splitPath(p)
+ expect_true(is.list(res))
+ expect_equal(names(res), c("drive", "path"))
+ expect_true(length(res$drive) == as.integer(isWindows()))
+ expect_true(is.character(res$path))
+ expect_true(length(res$path) >= 1L)
+
+ p = c("tmp", "foo", "", "bar")
+ res = splitPath(collapse(p, "/"))
+ expect_equal(tail(res$path, 3), p[-3])
+ res = splitPath(collapse(p, "\\"))
+ expect_equal(tail(res$path, 3), p[-3])
+})
diff --git a/tests/testthat/test_splitTime.R b/tests/testthat/test_splitTime.R
new file mode 100644
index 0000000..7027a9f
--- /dev/null
+++ b/tests/testthat/test_splitTime.R
@@ -0,0 +1,21 @@
+context("splitTime")
+
+test_that("splitTime", {
+ expect_equal(splitTime(0, "years"), c(years=0, days=0, hours=0, minutes=0, seconds=0))
+ expect_equal(splitTime(0, "days"), c(years=NA, days=0, hours=0, minutes=0, seconds=0))
+ expect_equal(splitTime(0, "hours"), c(years=NA, days=NA, hours=0, minutes=0, seconds=0))
+ expect_equal(splitTime(0, "minutes"), c(years=NA, days=NA, hours=NA, minutes=0, seconds=0))
+ expect_equal(splitTime(0, "seconds"), c(years=NA, days=NA, hours=NA, minutes=NA, seconds=0))
+
+ seconds = 2 * 365 * 24 * 60 * 60
+ expect_equal(splitTime(seconds, "years"), c(years=2, days=0, hours=0, minutes=0, seconds=0))
+ expect_equal(splitTime(seconds, "days"), c(years=NA, days=2 * 365, hours=0, minutes=0, seconds=0))
+ expect_equal(splitTime(seconds, "hours"),
+ c(years=NA, days=NA, hours=2 * 365 * 24, minutes=0, seconds=0))
+ expect_equal(splitTime(seconds, "minutes"),
+ c(years=NA, days=NA, hours=NA, minutes=2 * 365 * 24 * 60, seconds=0))
+ expect_equal(splitTime(seconds, "seconds"),
+ c(years=NA, days=NA, hours=NA, minutes=NA, seconds=seconds))
+
+ expect_true(is.integer(splitTime(100000, "minutes")))
+})
diff --git a/tests/testthat/test_strrepeat.R b/tests/testthat/test_strrepeat.R
new file mode 100644
index 0000000..a9f5ad1
--- /dev/null
+++ b/tests/testthat/test_strrepeat.R
@@ -0,0 +1,8 @@
+context("strrepeat")
+
+test_that("strrepeat", {
+ expect_identical(strrepeat("x", 3), "xxx")
+ expect_identical(strrepeat("x", 3, "y"), "xyxyx")
+ expect_identical(strrepeat(c("x", "y"), 2), "xyxy")
+})
+
diff --git a/tests/testthat/test_suppressAll.R b/tests/testthat/test_suppressAll.R
new file mode 100644
index 0000000..e26a5d5
--- /dev/null
+++ b/tests/testthat/test_suppressAll.R
@@ -0,0 +1,14 @@
+
+context("suppressAll")
+
+test_that("suppressAll", {
+ expect_equal(suppressAll(123), 123)
+ expect_output({print(123);0}, "123")
+ expect_silent(suppressAll({print(123);0}))
+
+ expect_warning(warning(123), "123")
+ expect_silent(suppressAll({warning(123);0}))
+
+ expect_message(message(123), "123")
+ expect_silent(suppressAll(message(123)))
+})
diff --git a/tests/testthat/test_symdiff.R b/tests/testthat/test_symdiff.R
new file mode 100644
index 0000000..6c1fff4
--- /dev/null
+++ b/tests/testthat/test_symdiff.R
@@ -0,0 +1,10 @@
+context("symdiff")
+
+test_that("symdiff", {
+ expect_equal(symdiff(c(1, 2), 1), 2)
+ expect_equal(symdiff(c(1, 2), numeric(0)), c(1, 2))
+ expect_equal(symdiff("a", "b"), c("a", "b"))
+ expect_equal(symdiff("a", "a"), character(0))
+})
+
+
diff --git a/tests/testthat/test_system3.R b/tests/testthat/test_system3.R
new file mode 100644
index 0000000..bb99309
--- /dev/null
+++ b/tests/testthat/test_system3.R
@@ -0,0 +1,39 @@
+context("system3")
+
+if (interactive()) {
+
+test_that("system3", {
+ d = tempfile()
+ dir.create(d)
+ fn = file.path(d, "foo.bar")
+ file.create(fn)
+
+ # no error
+ res = system3("ls", d)
+ expect_equal(res, list(exit.code=0L, output=as.character(NA)))
+ res = system3("ls", d, stdout=TRUE, stderr=TRUE)
+ expect_equal(res, list(exit.code=0L, output="foo.bar"))
+
+ # wrong command
+ res = system3("xxx", stop.on.exit.code=FALSE)
+ expect_equal(res, list(exit.code=127L, output=as.character(NA)))
+ expect_error(system3("xxx", stop.on.exit.code=TRUE),
+ "Command: xxx ; exit code: 127; output: NA")
+
+ # exit code
+ res = system3("ls", "xxx", stop.on.exit.code=FALSE)
+ expect_equal(res, list(exit.code=2L, output=as.character(NA)))
+ res = system3("ls", "xxx", stdout=TRUE, stderr=TRUE, stop.on.exit.code=FALSE)
+ msg = "ls: cannot access xxx: No such file or directory"
+ expect_equal(res$exit.code, 2L)
+ expect_true(grep("ls:", res$output) == 1)
+ expect_true(grep("xxx", res$output) == 1)
+ expect_error(system3("ls", "xxx", stdout=TRUE, stderr=TRUE, stop.on.exit.code=TRUE),
+ "Command: ls xxx; exit code: 2; output: ls:")
+ expect_error(system3("ls", "xxx", stdout=TRUE, stderr=TRUE, stop.on.exit.code=TRUE),
+ "xxx")
+ expect_error(system3("ls", c("1", "2"), stdout=TRUE, stderr=TRUE, stop.on.exit.code=TRUE),
+ "Command: ls")
+})
+
+}
diff --git a/tests/testthat/test_toRangeStr.R b/tests/testthat/test_toRangeStr.R
new file mode 100644
index 0000000..b1e08d4
--- /dev/null
+++ b/tests/testthat/test_toRangeStr.R
@@ -0,0 +1,31 @@
+context("toRangeStr")
+
+expect_range = function(x, str, ...) {
+ expect_equal(toRangeStr(x, ...), str)
+ expect_equal(toRangeStr(sample(x), ...), str)
+ expect_equal(toRangeStr(sample(c(x, x)), ...), str)
+ expect_equal(toRangeStr(sample(c(x, x)), ...), str)
+}
+
+test_that("continuous ranges", {
+ x = c(1, 2, 3, 4, 5, 6)
+ expect_range(x, "1 - 6")
+ expect_range(x, "1_6", range.sep="_")
+})
+
+test_that("single number", {
+ x = 1
+ expect_range(x, "1")
+})
+
+test_that("negative numbers", {
+ x = -2:4
+ expect_range(x, "-2 - 4")
+})
+
+test_that("noncontinuous ranges", {
+ x = c(-5, -4, -2, 0, 2, 3, 4, 7)
+ expect_range(x, "-5 - -4, -2, 0, 2 - 4, 7")
+})
+
+
diff --git a/tests/testthat/test_which.first.last.R b/tests/testthat/test_which.first.last.R
new file mode 100644
index 0000000..12134c1
--- /dev/null
+++ b/tests/testthat/test_which.first.last.R
@@ -0,0 +1,27 @@
+context("which.first / which.last")
+
+test_that("which.first / which.last", {
+ x = c(FALSE, TRUE, FALSE, TRUE)
+ expect_equal(which.first(x), 2L)
+ expect_equal(which.last(x), 4L)
+
+ x = setNames(x, head(letters, length(x)))
+ expect_equal(which.first(x), setNames(2L, "b"))
+ expect_equal(which.last(x), setNames(4L, "d"))
+ expect_equal(which.first(x, use.names=FALSE), 2L)
+ expect_equal(which.last(x, use.names=FALSE), 4L)
+
+ x = c(NA, TRUE, NA, TRUE, NA)
+ expect_equal(which.first(x), 2L)
+ expect_equal(which.last(x), 4L)
+
+ x = logical(0L)
+ expect_equal(which.first(x), integer(0L))
+ expect_equal(which.last(x), integer(0L))
+ expect_equal(which.first(x, use.names=FALSE), integer(0L))
+ expect_equal(which.last(x, use.names=FALSE), integer(0L))
+
+ x = c(NA, NA)
+ expect_equal(which.first(x), integer(0L))
+ expect_equal(which.last(x), integer(0L))
+})
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/r-cran-bbmisc.git
More information about the debian-med-commit
mailing list