plyr/0000755000176000001440000000000012060050143011257 5ustar ripleyusersplyr/MD50000644000176000001440000002270212060050143011572 0ustar ripleyusers9b663d59b979371b6a101f6c0514a156 *DESCRIPTION 2fa4b4cc08cfe312801d77dab73ebc3a *NAMESPACE 37f7eb2a168c9ca03d9856e20387903f *NEWS b30083458b44dd0ebdb6573f81cbaf09 *R/a_ply.r 051d8e915e9d4fd1d37baba2c8540cd3 *R/aaply.r 7518e52d3fffabe64480674f0c0841fb *R/adply.r effba88914db9ef403f64b4b0d00a8d5 *R/alply.r 27850e8a34d803a77059aee92fe98a51 *R/arrange.r dbaeb0f7ac128903161538fa22f26da7 *R/colwise.r bab38e28e3e345d2bea2ee72f682e220 *R/count.r f05b9167d486f77d2eaecaee67eb416f *R/d_ply.r fb6dcb53dca0a98cf6a1da120c2c478d *R/daply.r 9ec2eb1767f801a2f9783af803cac212 *R/data-frame.r 526de3e3bf03679c79a9b4165d6cc128 *R/data.r 6c4c8ef405dac560c9441f3a59cc1648 *R/ddply.r 201c9ac2be5dfa8fa52575e9b459bb64 *R/defaults.r a18f14f7e0a6f50360586504d1311227 *R/dimensions.r fabcd1e2c375a3861200a934b924074a *R/dlply.r 099f05c40f96cc0e0e9bc5bb1e33cfac *R/each.r dcaa350d0ab003f6ad12e4d18f5eef90 *R/here.r 6573fcf86598a272fe60ce9cd86d7015 *R/id.r 8d38e8274a1e6e549456888e314509e4 *R/idataframe.r d31d1c394a815adaa016acb562de0842 *R/indexed-array.r 2dd51053e2dd003d3c46ed3a2f6fa459 *R/indexed-data-frame.r 0cc320306148b4c9e00cc7ead82cbd12 *R/indexed.r aeb3707b4a7ffae8af0e9237f3f67e72 *R/join-all.r f4572136e8a85fdd0bd77a2216bb557d *R/join.r 154acfdcc1ea3b63cc80151d69d8c734 *R/l_ply.r 49db6bd50575429654a36aec5fca75dc *R/laply.r 7e06f4ff7fba5ce7e93c39331e7b2fdd *R/ldply.r 61a3bea3cc93368b6ac6f453a0ae3744 *R/liply.r 0a2810798164088dda8d4e31e0891ff2 *R/list-to-array.r ab9cd1a82d137c652e71324eb25dec70 *R/list-to-dataframe.r 0235ddca614287ca137a2a5ec80b6ecc *R/list-to-vector.r fe85fcdb0225eb6ac7812ff3a9aac5ba *R/llply.r a111fc796dbb2bb6d98e8c7a44a3cf16 *R/loop-apply.r 138f6c83d529bbf8c68f8830d7081570 *R/m_ply.r 233c43c50f214fb7b6cb4da744bda204 *R/maply.r 8c2d4fbdc639835b6a7d5fa2f01f0026 *R/match-df.r cdf123cbd9772e88f6a1238f60b77078 *R/mdply.r f8952eb7391ea62de7b94494f2734d23 *R/mlply.r fb0da67095913ebc3e7dc368e6410ca2 *R/mutate.r 7787cd67a1bd78ff9b8169cc55015e3c *R/name-rows.r 56cf70c7362e1f76ddf82672b8444b5c *R/parallel.r 65cad21d5e61b3c53af0278540715656 *R/plyr.r eb8917263bad12770cd32445403be25c *R/progress-time.r b413617b9c819a43a15cc1b450b88cdc *R/progress.r 87b4723fec09c203ea9c98373d87cb4b *R/quickdf.r 1baea22f9ff11a3cafa901689d1cc1bc *R/quote.r 14fe46cf226a4774cb05fc4e7aede76f *R/r_ply.r c5b6f32a7d4ceba0b201ed58d6d3b989 *R/raply.r 9f5486ed284127abbdd22cd9ce783f4f *R/rbind-fill-matrix.r d772aca0b29a04520372a22ec6c6a474 *R/rbind-fill.r 746027418d6df16e5ab63e10aafe7772 *R/rdply.r 483e90a4ad2aebccc73c5ddd1b32503d *R/rename.r 4921126fc5506e7ab00ac924cf937cc2 *R/revalue.r d44675874eccaa49892e11a11ea9ebba *R/rlply.r ca9e3ea0a3d9e47854bfcb533fdad53b *R/round-any.r 7369a7d69027736f1e62f0f49fa8aed6 *R/splat.r cef16fac9a4a53ffa46169dfd3ebcc91 *R/split-indices.r 29e4abb6bc1f7561ff08c08554ccb58c *R/split.r c80b8aa598ab1329699f201d414a3ef6 *R/splitter-a.r ecbe80157dbd628a6c741f90c56d0fcb *R/splitter-d.r c3f4bc5baaa2be00a96fae50f235097a *R/strip-splits.r d6dbd2b5909f72f5ec28c6e3cff1c3ed *R/summarise.r 632a3d93a68172b1350d5f23151c0f0c *R/take.r d1c1587c3f3056b2a17c6085a1e0d8e2 *R/try.r d2189ca6934b505c385b70e66165e298 *R/utils-functional.r e7f9e2adc241a3f9ad0ab2e26e2aedb1 *R/utils.r 3d73325ab592dff535a8e7bd8e869967 *R/vaggregate.r 8f61b6486addfcd6b8b079cd6add0e9c *README.md 9b2d63a08f6c4d1718642d2c904c230a *data/baseball.rda 12d6f72bbc8c97a10e7c4c235aab3ae3 *data/ozone.rda c064ec8464bce62b7862acec50e8475b *inst/CITATION d564b7820ed6c9598ef0e9f39913a4dc *inst/tests/quickdf.r 71b3d690155f10491a0c36295fcca10a *inst/tests/test-array.r 9df6700af6e72c3afcea6d488917972e *inst/tests/test-count.r 64843ae8890dedb58491b0c68b7d5e41 *inst/tests/test-data-frame.r 570589b2d8f6a5e7a5a9292bde0255c3 *inst/tests/test-empty.r 22fb32944156a59fb79d4b9b9185f685 *inst/tests/test-idf.r edcb617aef78240a4aab68b4d9eef8b9 *inst/tests/test-join.r de3b9fe325bde5a4d7ae4fee2b124dd4 *inst/tests/test-list.r e4a2dbcd3e829d98895ac697916dbfc5 *inst/tests/test-mapply.r f0b164f2304fbef1573b5859032a81ba *inst/tests/test-mutate.r b4ffb0e168d64cfb2337467d5949bb87 *inst/tests/test-ninteraction.r 148c66709e0a612190930417b891569e *inst/tests/test-parallel.r 5edbe06f3ef5ca4afebae668d5f72394 *inst/tests/test-progress.r af8f0160f64ccc89202dd1c6fd4255ad *inst/tests/test-quote.r d6275e43a3f6b046422f88c65323bc26 *inst/tests/test-rbind.matrix.r 680dccdcc148e4b95ca0d9216e2d8289 *inst/tests/test-rbind.r 0db4452cb3b1aebc91a230ec4152d8b4 *inst/tests/test-rename.r 92f8e58ba0c83bb0c1c3e333bc3ffe55 *inst/tests/test-replicate.r f2b44485ec854cfc9e68c44d5fbc630b *inst/tests/test-revalue.r 3b4322ac83b50f5a1a370c07c8f5d92b *inst/tests/test-simplify-df.r 8333352212f7d58b1e53ce26a60afb5f *inst/tests/test-split-data-frame.r fe3ec6775a168e58a03f54a4b2324596 *inst/tests/test-split-indices.r 9dd79657465c4e2ab72d4209f047854b *inst/tests/test-split-labels.r dc9ed90dded1449345037dce24ba8c79 *inst/tests/test-summarise.r 49ea637ae8cb2562fe7b5c102ac10559 *man/a_ply.Rd ce52ec32036bd6ddf088b33155bdf7b4 *man/aaply.Rd fc292562290ffb4d124ff2907090b5ce *man/adply.Rd 9e97ae53b984ab36fba6e004295a085e *man/alply.Rd dfff8dc0d6841b6b437875342bb784dd *man/amv_dim.Rd 144600b773ec891d73e4a109b60b153b *man/amv_dimnames.Rd 8ab0a5af25222d56a4315c092796f9d4 *man/arrange.Rd 30bf0f3c6fc678900168bac2f015ded6 *man/as.data.frame.function.Rd 2a5482715255383f335065d8a6d7d8ae *man/as.list.split.Rd 0efc6aa43e0d9eb9eeb89fee250e4c96 *man/as.quoted.Rd de25bd94213ee4dd760b525ddefd45b2 *man/baseball.Rd 10a6252651f974b732dd6c1af3b14467 *man/colwise.Rd 27e6c58afc383e8f66bb02568a7bd007 *man/compact.Rd 938c1d38daf1e20f1dec95862ab78be4 *man/count.Rd 06c0a8d42784a7f307b08623b9c895a3 *man/create_progress_bar.Rd 63408510df419a00edd6f6467572bd96 *man/d_ply.Rd ea421a939afbb16459398b1118fa86a7 *man/daply.Rd 1898a193a4ddc66e3a5bfd1eac362f22 *man/ddply.Rd 598e17cddf0197cd109324b6e793e2a7 *man/defaults.Rd 6b88af2bb271b3a0c4f4e7317deb6ab7 *man/desc.Rd 3715aa08855964d4330e187d7d486b16 *man/dims.Rd 76221834bab7a319e98439e8e77ef9c7 *man/dlply.Rd fdf29018b750e2f3d94a75b9c87d0170 *man/each.Rd 15b8fca1da5a1d13124297ff1a69036b *man/empty.Rd c372bd8f82bf880e2e91f4b5dbb55b6c *man/eval.quoted.Rd 90421f580f1c9692f41f2422e014d584 *man/failwith.Rd 7ae0a790c8276dcee9e0cf627003ffbd *man/get-split.Rd 6397abb97a76e9f28bb62f44827b2777 *man/here.Rd 2c17345f244448c628b8616d743c5002 *man/id.Rd c7b3d72280561f2fe93371bc1a37061d *man/id_var.Rd 485099a413e4731b7cf14a4184744e73 *man/idata.frame.Rd 840f66765d63837a329a6297926ab66e *man/indexed_array.Rd 06dc046ae9c663debbe953e9f49ba7e1 *man/indexed_df.Rd 85ead63b1217af3ef8fdfe007e01cfe4 *man/is.discrete.Rd b6e6fad38ecf71f9333b8ac9520786bb *man/is.formula.Rd bb37d48d1c298ea013748f1c01866975 *man/isplit2.Rd b396bc6d3cc7d38555911ce1e63250e9 *man/join.Rd ec9d2d7fc41be3fa106cc534222426d0 *man/join.keys.Rd 97587fef54e4fdf7effc02740a4f0a9e *man/join_all.Rd dfe4750fdf4923e3104ffaaf131776c7 *man/l_ply.Rd 16d71e2c8e67a223d8f84b0f7ec499be *man/laply.Rd 934ef2296ac98ee0e0cc4e39f96e69d9 *man/ldply.Rd 7516a16cb60cf27566dc51c0046fc138 *man/liply.Rd 629de84d5032c86d038012340ba02b8f *man/list_to_array.Rd 4a476049a866905659cdf070dd9727a2 *man/list_to_dataframe.Rd 862688bd52d3cab5daf4d8f1511f138b *man/list_to_vector.Rd c230664131ce3aacccdaaf4ddb68ec35 *man/llply.Rd 1d1821666ac2124fc476fa512abb8200 *man/loop_apply.Rd 6cfa6ff8f8e9dd5a84fc7c770425fc9f *man/m_ply.Rd 3fed62ee065293b23f7b079c1d7f497f *man/maply.Rd 499659e175a892fe417828493a319b78 *man/mapvalues.Rd bd78c0cdf780b4bada59979f2ae1b99c *man/match_df.Rd a8238f408548022f6d4848226291e0cf *man/mdply.Rd bc809f5e6aa94fcb3df99d733503b284 *man/mlply.Rd 2d0c92444909eb8f009df5f3e21bb091 *man/mutate.Rd 62c79cc73057d579d576328ae58a4d25 *man/name_rows.Rd c559d1372836dbd9b8d603c7631fa023 *man/names.quoted.Rd 5008ea2c544983f5a8ad9b51367ee642 *man/nunique.Rd d2710642ac44b64f9f43fd08f8237e15 *man/ozone.Rd 9685e33922cf6f5a69c55af08205cc72 *man/plyr.Rd 4294d4956a0321e27c5e38799bf20613 *man/print.quoted.Rd 73a288e900f81f9cbb37dd7f323c4946 *man/print.split.Rd f7bff61b6aa741fd33c61909c57ac5be *man/progress_none.Rd 75050a56b20299646c38082b34c3d97c *man/progress_text.Rd c2373c71158781240ce95d96294f6e27 *man/progress_time.Rd 2ca810721d1ea1db287d333158a1d692 *man/progress_tk.Rd 0e3c94f6895b7218f7c0aa60be62a409 *man/progress_win.Rd 13212fc5e1602a6a5f06e90cabe390bf *man/quickdf.Rd 32590979c2f2c53d84dcc634b102c5e7 *man/quoted.Rd 2a52a63c04e805bb604e8e68f95e01a0 *man/r_ply.Rd d07d0e83bbbe03417ae22ca158ce55d5 *man/raply.Rd d7811882a3cb607dd5ff4fc71d81a39c *man/rbind.fill.Rd 615864fe9a2917d474be097fd10e3c70 *man/rbind.fill.matrix.Rd b16dd4428fe00cd8c7af4f9368570fca *man/rdply.Rd 15caff5bb35366d7161fb8ddd00328d7 *man/reduce_dim.Rd 4925909bd5e4e4fa668da77200865be2 *man/rename.Rd 84ed21424b2528e4f4e75453ef045f66 *man/revalue.Rd ed68d9045b8faa3790fa42c6d96d264d *man/rlply.Rd 3636bd0de16181a7b32d6fa38af00bd0 *man/round_any.Rd 9c974ee3f4474ac74c9c9a60f662cb03 *man/splat.Rd 8a1d5936fd6a63480f33890a26102ba7 *man/split_indices.Rd dcbea80602c0d5c9626b6ea2de228f94 *man/split_labels.Rd 34f4376f16955b48a7e7bc463083efad *man/splitter_a.Rd 4e5bb4f6cda668c8c823fbd1ad96a651 *man/splitter_d.Rd 73169417e97bf94ab6fd2da68ffb6526 *man/strip_splits.Rd 04da1fd0201904b43c42917089026113 *man/summarise.Rd 698bab1ef9ddd92aa29af5f252e7e4ff *man/take.Rd f965825f4813cb5890c5afb6cc8d7690 *man/true.Rd 29f454fa61e816d69cff2ba1993e699f *man/try_default.Rd dbafa9f424846e45f77e9d961b1ef717 *man/tryapply.Rd 1268056f8d0e765ad0f99af317a906ab *man/unrowname.Rd 2ea2af25c66ef2a745886cbd9b640353 *man/vaggregate.Rd 021c0a6dbed105a81284fb031280df1d *src/loop-apply.c 9e136c2fbd222ce76ba3d0bfa05d7e80 *src/split-numeric.c a16ff31afc22b8d7893bfcb504d98355 *tests/test-all.R plyr/tests/0000755000176000001440000000000012035657220012434 5ustar ripleyusersplyr/tests/test-all.R0000644000176000001440000000006612034020365014277 0ustar ripleyuserslibrary(testthat) library(plyr) test_package("plyr") plyr/src/0000755000176000001440000000000012057740163012064 5ustar ripleyusersplyr/src/split-numeric.c0000644000176000001440000000155212057740163015026 0ustar ripleyusers#include #include SEXP split_indices(SEXP group, SEXP n) { SEXP vec; int i, j, k; int nlevs = INTEGER(n)[0]; int nobs = LENGTH(group); int *pgroup = INTEGER(group); // Count number of cases in each group int counts[nlevs]; for (i = 0; i < nlevs; i++) counts[i] = 0; for (i = 0; i < nobs; i++) { j = pgroup[i]; if (j > nlevs) error("n smaller than largest index"); counts[j - 1]++; } // Allocate storage for results PROTECT(vec = allocVector(VECSXP, nlevs)); for (i = 0; i < nlevs; i++) { SET_VECTOR_ELT(vec, i, allocVector(INTSXP, counts[i])); } // Put indices in groups for (i = 0; i < nlevs; i++) { counts[i] = 0; } for (i = 0; i < nobs; i++) { j = pgroup[i] - 1; k = counts[j]; INTEGER(VECTOR_ELT(vec, j))[k] = i + 1; counts[j]++; } UNPROTECT(1); return vec; } plyr/src/loop-apply.c0000644000176000001440000000107512057740163014327 0ustar ripleyusers#include #include SEXP loop_apply(SEXP n, SEXP f, SEXP rho) { if(!isFunction(f)) error("'f' must be a function"); if(!isEnvironment(rho)) error("'rho' should be an environment"); int n1 = INTEGER(n)[0]; SEXP results, R_fcall; PROTECT(results = allocVector(VECSXP, n1)); PROTECT(R_fcall = lang2(f, R_NilValue)); SEXP ii; for(int i = 0; i < n1; i++) { PROTECT(ii = ScalarInteger(i + 1)); SETCADR(R_fcall, ii); SET_VECTOR_ELT(results, i, eval(R_fcall, rho)); UNPROTECT(1); } UNPROTECT(2); return results; } plyr/README.md0000644000176000001440000000272312034020703012542 0ustar ripleyusers# plyr plyr is a set of tools for a common set of problems: you need to __split__ up a big data structure into homogeneous pieces, __apply__ a function to each piece and then __combine__ all the results back together. For example, you might want to: * fit the same model each patient subsets of a data frame * quickly calculate summary statistics for each group * perform group-wise transformations like scaling or standardising It's already possible to do this with base R functions (like split and the apply family of functions), but plyr makes it all a bit easier with: * totally consistent names, arguments and outputs * convenient parallelisation through the foreach package * input from and output to data.frames, matrices and lists * progress bars to keep track of long running operations * built-in error recovery, and informative error messages * labels that are maintained across all transformations Considerable effort has been put into making plyr fast and memory efficient, and in many cases plyr is as fast as, or faster than, the built-in equivalents. A detailed introduction to plyr has been published in JSS: "The Split-Apply-Combine Strategy for Data Analysis", http://www.jstatsoft.org/v40/i01/. You can find out more at http://had.co.nz/plyr/, or track development at http://github.com/hadley/plyr. You can ask questions about plyr (and data manipulation in general) on the plyr mailing list. Sign up at http://groups.google.com/group/manipulatr. plyr/R/0000755000176000001440000000000012057740163011476 5ustar ripleyusersplyr/R/vaggregate.r0000644000176000001440000000400712057432511013771 0ustar ripleyusers#' Vector aggregate. #' #' This function is somewhat similar to \code{tapply}, but is designed for #' use in conjunction with \code{id}. It is simpler in that it only #' accepts a single grouping vector (use \code{\link{id}} if you have more) #' and uses \code{\link{vapply}} internally, using the \code{.default} value #' as the template. #' #' \code{vaggregate} should be faster than \code{tapply} in most situations #' because it avoids making a copy of the data. #' #' @param .value vector of values to aggregate #' @param .group grouping vector #' @param .fun aggregation function #' @param ... other arguments passed on to \code{.fun} #' @param .default default value used for missing groups. This argument is #' also used as the template for function output. #' @param .n total number of groups #' @export #' @examples #' # Some examples of use borrowed from ?tapply #' n <- 17; fac <- factor(rep(1:3, length = n), levels = 1:5) #' table(fac) #' vaggregate(1:n, fac, sum) #' vaggregate(1:n, fac, sum, .default = NA_integer_) #' vaggregate(1:n, fac, range) #' vaggregate(1:n, fac, range, .default = c(NA, NA) + 0) #' vaggregate(1:n, fac, quantile) #' # Unlike tapply, vaggregate does not support multi-d output: #' tapply(warpbreaks$breaks, warpbreaks[,-1], sum) #' vaggregate(warpbreaks$breaks, id(warpbreaks[,-1]), sum) #' #' # But it is about 10x faster #' x <- rnorm(1e6) #' y1 <- sample.int(10, 1e6, replace = TRUE) #' system.time(tapply(x, y1, mean)) #' system.time(vaggregate(x, y1, mean)) vaggregate <- function(.value, .group, .fun, ..., .default = NULL, .n = nlevels(.group)) { if (!is.integer(.group)) { if (is.list(.group)) { .group <- id(.group) } else { .group <- id(list(.group)) } } if (is.null(.default)) { .default <- .fun(.value[0], ...) } fun <- function(i) { if (length(i) == 0) return(.default) .fun(.value[i], ...) } indices <- split_indices(.group, .n) vapply(indices, fun, .default) } nlevels <- function(x) { n <- attr(x, "n") if (!is.null(n)) n else max(x) } plyr/R/utils.r0000644000176000001440000000315512035607412013020 0ustar ripleyusers#' Determine if a vector is discrete. #' #' A discrete vector is a factor or a character vector #' #' @param x vector to test #' @keywords internal #' @export #' @examples #' is.discrete(1:10) #' is.discrete(c("a", "b", "c")) #' is.discrete(factor(c("a", "b", "c"))) is.discrete <- function(x) is.factor(x) || is.character(x) || is.logical(x) #' Un-rowname. #' #' Strip rownames from an object #' #' @keywords internal #' @param x data frame #' @export unrowname <- function(x) { rownames(x) <- NULL x } #' Function that always returns true. #' #' @param ... all input ignored #' @return \code{TRUE} #' @keywords internal #' @seealso \code{\link{colwise}} which uses it #' @export true <- function(...) TRUE #' Compact list. #' #' Remove all NULL entries from a list #' #' @param l list #' @keywords manip internal #' @export compact <- function(l) Filter(Negate(is.null), l) #' Number of unique values. #' #' Calculate number of unique values of a variable as efficiently as possible. #' #' @param x vector #' @keywords internal nunique <- function(x) { if (is.factor(x)) { length(levels(x)) } else { length(unique(x)) } } #' Check if a data frame is empty. #' #' Empty if it's null or it has 0 rows or columns #' #' @param df data frame to check #' @keywords internal #' @export empty <- function(df) { (is.null(df) || nrow(df) == 0 || ncol(df) == 0) } "%||%" <- function(a, b) if (is.null(a)) b else a .matrix_to_df <- function(.data) { cnames <- colnames(.data) if (is.null(cnames)) cnames <- rep("", ncol(.data)) .data <- as.data.frame(.data, stringsAsFactors = FALSE) colnames(.data) <- cnames .data } plyr/R/utils-functional.r0000644000176000001440000000043112034020705015143 0ustar ripleyusers# f <- function(...) { # dots() # } # g <- function() { # f <- function(x, y, ...) { # dots() # } # f(x = 1, y = 2, z = 3) # } dots <- function() { call <- sys.call(-1) def <- eval(call[[1]], parent.frame(2)) match.call(def, call, expand.dots = FALSE)$`...` } plyr/R/try.r0000644000176000001440000000300612034020705012462 0ustar ripleyusers#' Fail with specified value. #' #' Modify a function so that it returns a default value when there is an #' error. #' #' @param default default value #' @param f function #' @param quiet all error messages be suppressed? #' @return a function #' @seealso \code{\link{try_default}} #' @keywords debugging #' @export #' @examples #' f <- function(x) if (x == 1) stop("Error!") else 1 #' \dontrun{ #' f(1) #' f(2) #' } #' #' safef <- failwith(NULL, f) #' safef(1) #' safef(2) failwith <- function(default = NULL, f, quiet = FALSE) { f <- match.fun(f) function(...) try_default(f(...), default, quiet = quiet) } #' Try, with default in case of error. #' #' \code{try_default} wraps try so that it returns a default value in the case of error. #' #' \code{tryNULL} provides a useful special case when dealing with lists. #' #' @param expr expression to try #' @param default default value in case of error #' @param quiet should errors be printed (TRUE) or ignored (FALSE, default) #' @aliases try_default tryNULL #' @export #' @keywords internal #' @seealso \code{\link{tryapply}} try_default <- function(expr, default, quiet = FALSE) { result <- default if (quiet) { tryCatch(result <- expr, error = function(e) {}) } else { try(result <- expr) } result } tryNULL <- function(expr) try_default(expr, NULL, quiet = TRUE) #' Apply with built in try. #' Uses compact, lapply and tryNULL #' #' @keywords internal #' @export tryapply <- function(list, fun, ...) { compact(lapply(list, function(x) tryNULL(fun(x, ...)))) } plyr/R/take.r0000644000176000001440000000133112035657174012610 0ustar ripleyusers#' Take a subset along an arbitrary dimension #' #' @param x matrix or array to subset #' @param along dimension to subset along #' @param indices the indices to select #' @param drop should the dimensions of the array be simplified? Defaults #' to \code{FALSE} which is the opposite of the useful R default. #' @export #' @examples #' x <- array(seq_len(3 * 4 * 5), c(3, 4, 5)) #' take(x, 3, 1) #' take(x, 2, 1) #' take(x, 1, 1) #' take(x, 3, 1, drop = TRUE) #' take(x, 2, 1, drop = TRUE) #' take(x, 1, 1, drop = TRUE) take <- function(x, along, indices, drop = FALSE) { nd <- length(dim(x)) index <- as.list(rep(TRUE, nd)) index[along] <- indices eval(as.call(c(as.name("["), as.name("x"), index, drop = drop))) } plyr/R/summarise.r0000644000176000001440000000303512057431371013665 0ustar ripleyusers#' Summarise a data frame. #' #' Summarise works in an analagous way to transform, except instead of adding #' columns to an existing data frame, it creates a new data frame. This is #' particularly useful in conjunction with \code{\link{ddply}} as it makes it #' easy to perform group-wise summaries. #' #' @param .data the data frame to be summarised #' @param ... further arguments of the form var = value #' @keywords manip #' @aliases summarise summarize #' @export summarise summarize #' @examples #' # Let's extract the number of teams and total period of time #' # covered by the baseball dataframe #' summarise(baseball, #' duration = max(year) - min(year), #' nteams = length(unique(team))) #' # Combine with ddply to do that for each separate id #' ddply(baseball, "id", summarise, #' duration = max(year) - min(year), #' nteams = length(unique(team))) summarise <- function(.data, ...) { stopifnot(is.data.frame(.data) || is.list(.data) || is.environment(.data)) cols <- as.list(substitute(list(...))[-1]) # ... not a named list, figure out names by deparsing call if(is.null(names(cols))) { missing_names <- rep(TRUE, length(cols)) } else { missing_names <- names(cols) == "" } if (any(missing_names)) { names <- unname(unlist(lapply(match.call(expand.dots = FALSE)$`...`, deparse))) names(cols)[missing_names] <- names[missing_names] } .data <- as.list(.data) for (col in names(cols)) { .data[[col]] <- eval(cols[[col]], .data, parent.frame()) } quickdf(.data[names(cols)]) } summarize <- summarise plyr/R/strip-splits.r0000644000176000001440000000103512034020705014321 0ustar ripleyusers#' Remove splitting variables from a data frame. #' #' This is useful when you want to perform some operation to every column #' in the data frame, except the variables that you have used to split it. #' These variables will be automatically added back on to the result when #' combining all results together. #' #' @param df data frame produced by \code{d*ply}. #' @export #' @examples #' dlply(mtcars, c("vs", "am")) #' dlply(mtcars, c("vs", "am"), strip_splits) strip_splits <- function(df) { df[setdiff(names(df), attr(df, "vars"))] } plyr/R/splitter-d.r0000644000176000001440000000571612035041360013746 0ustar ripleyusers#' Split a data frame by variables. #' #' Split a data frame into pieces based on variable contained in that data frame #' #' This is the workhorse of the \code{d*ply} functions. Based on the variables #' you supply, it breaks up a single data frame into a list of data frames, #' each containing a single combination from the levels of the specified #' variables. #' #' This is basically a thin wrapper around \code{\link{split}} which #' evaluates the variables in the context of the data, and includes enough #' information to reconstruct the labelling of the data frame after #' other operations. #' #' @seealso \code{\link{.}} for quoting variables, \code{\link{split}} #' @family splitter functions #' @param data data frame #' @param .variables a \link{quoted} list of variables #' @param drop drop unnused factor levels? #' @return a list of data.frames, with attributes that record split details #' @keywords internal #' @examples #' plyr:::splitter_d(mtcars, .(cyl)) #' plyr:::splitter_d(mtcars, .(vs, am)) #' plyr:::splitter_d(mtcars, .(am, vs)) #' #' mtcars$cyl2 <- factor(mtcars$cyl, levels = c(2, 4, 6, 8, 10)) #' plyr:::splitter_d(mtcars, .(cyl2), drop = TRUE) #' plyr:::splitter_d(mtcars, .(cyl2), drop = FALSE) #' #' mtcars$cyl3 <- ifelse(mtcars$vs == 1, NA, mtcars$cyl) #' plyr:::splitter_d(mtcars, .(cyl3)) #' plyr:::splitter_d(mtcars, .(cyl3, vs)) #' plyr:::splitter_d(mtcars, .(cyl3, vs), drop = FALSE) splitter_d <- function(data, .variables = NULL, drop = TRUE) { stopifnot(is.quoted(.variables)) if (length(.variables) == 0) { splitv <- rep(1, nrow(data)) split_labels <- NULL attr(splitv, "n") <- max(splitv) vars <- character(0) } else { splits <- eval.quoted(.variables, data) splitv <- id(splits, drop = drop) split_labels <- split_labels(splits, drop = drop, id = splitv) vars <- unlist(lapply(.variables, all.vars)) } index <- split_indices(as.integer(splitv), attr(splitv, "n")) il <- indexed_df(data, index, vars) structure( il, class = c(class(il), "split", "list"), split_type = "data.frame", split_labels = split_labels ) } #' Generate labels for split data frame. #' #' Create data frame giving labels for split data frame. #' #' @param list of variables to split up by #' @param whether all possible combinations should be considered, or only those present in the data #' @keywords internal #' @export split_labels <- function(splits, drop, id = plyr::id(splits, drop = TRUE)) { if (length(splits) == 0) return(data.frame()) if (drop) { # Need levels which occur in data representative <- which(!duplicated(id))[order(unique(id))] quickdf(lapply(splits, function(x) x[representative])) } else { unique_values <- llply(splits, ulevels) names(unique_values) <- names(splits) rev(expand.grid(rev(unique_values), stringsAsFactors = FALSE)) } } ulevels <- function(x) { if (is.factor(x)) { levs <- levels(x) factor(levs, levels = levs) } else { sort(unique(x)) } } plyr/R/splitter-a.r0000644000176000001440000000544312034030034013733 0ustar ripleyusers#' Split an array by .margins. #' #' Split a 2d or higher data structure into lower-d pieces based #' #' This is the workhorse of the \code{a*ply} functions. Given a >1 d #' data structure (matrix, array, data.frame), it splits it into pieces #' based on the subscripts that you supply. Each piece is a lower dimensional #' slice. #' #' The margins are specified in the same way as \code{\link{apply}}, but #' \code{splitter_a} just splits up the data, while \code{apply} also #' applies a function and combines the pieces back together. This function #' also includes enough information to recreate the split from attributes on #' the list of pieces. #' #' @param data >1d data structure (matrix, data.frame or array) #' @param .margins a vector giving the subscripts to split up \code{data} by. # 1 splits up by rows, 2 by columns and c(1,2) by rows and columns #' @param .expand if splitting a dataframe by row, should output be 1d #' (expand = FALSE), with an element for each row; or nd (expand = TRUE), #' with a dimension for each variable. #' @return a list of lower-d slices, with attributes that record split details #' @family splitter functions #' @keywords internal #' @examples #' plyr:::splitter_a(mtcars, 1) #' plyr:::splitter_a(mtcars, 2) #' #' plyr:::splitter_a(ozone, 2) #' plyr:::splitter_a(ozone, 3) #' plyr:::splitter_a(ozone, 1:2) splitter_a <- function(data, .margins = 1L, .expand = TRUE) { .margins <- as.integer(.margins) if (length(.margins) == 0) { return(list(data)) } if (!all(.margins %in% seq_len(dims(data)))) stop("Invalid margin") dimensions <- lapply(amv_dim(data), seq_len) dimensions[-.margins] <- list("") indices <- expand.grid(dimensions, KEEP.OUT.ATTRS = FALSE, stringsAsFactors = FALSE) names(indices) <- paste("X", 1:ncol(indices), sep="") # Ensure indices are ordered in the way in which they should appear in the # output - last margin varies fastest ord <- do.call(order, indices[rev(.margins)]) indices <- unrowname(indices[ord, , drop = FALSE]) il <- indexed_array(environment(), indices) if (is.data.frame(data) && .expand && identical(.margins, 1L)) { split_labels <- data } else { if (is.data.frame(data)) { dnames <- list(seq_len(nrow(data)), names(data)) } else { dnames <- amv_dimnames(data) dnames <- lapply(dnames, function(x) factor(x, levels = x)) } raw <- mapply("[", dnames[.margins], indices[.margins], SIMPLIFY = FALSE) split_labels <- data.frame(raw, stringsAsFactors = FALSE) if (!is.null(names(dnames))) { names(split_labels) <- names(dnames)[.margins] } else { names(split_labels) <- paste("X", seq_along(.margins), sep = "") } } structure( il, class = c(class(il), "split", "list"), split_type = "array", split_labels = split_labels ) } plyr/R/split.r0000644000176000001440000000203212034020705012775 0ustar ripleyusers#' Subset splits. #' #' Subset splits, ensuring that labels keep matching #' #' @keywords internal #' @param x split object #' @param i index #' @param ... unused #' @method [ split #' @rdname get-split #' @export "[.split" <- function(x, i, ...) { structure( NextMethod(), class = c("split", "list"), split_type = attr(x, "split_type"), split_labels = attr(x, "split_labels")[i, , drop = FALSE] ) } #' Convert split list to regular list. #' #' Strip off label related attributed to make a strip list as regular list #' #' @keywords internal #' @param x object to convert to a list #' @param ... unused #' @method as.list split #' @export as.list.split <- function(x, ...) { attr(x, "split_type") <- NULL attr(x, "split_labels") <- NULL class(x) <- setdiff(class(x), "split") x } #' Print split. #' #' Don't print labels, so it appears like a regular list #' #' @keywords internal #' @param x object to print #' @param ... unused #' @method print split #' @export print.split <- function(x, ...) { print(as.list(x)) } plyr/R/split-indices.r0000644000176000001440000000101712043514645014426 0ustar ripleyusers#' Split indices. #' #' An optimised version of split for the special case of splitting row #' indices into groups, as used by \code{\link{splitter_d}} #' #' @param index integer indices #' @param group integer groups #' @param n largest integer (may not appear in index) #' @useDynLib plyr #' @keywords internal manip #' @export split_indices <- function(group, n = max(group)) { if (length(group) == 0) return(integer()) stopifnot(is.integer(group)) n <- as.integer(n) .Call("split_indices", group, as.integer(n)) } plyr/R/splat.r0000644000176000001440000000131412034020705012767 0ustar ripleyusers#' `Splat' arguments to a function. #' #' Wraps a function in do.call, so instead of taking multiple arguments, it #' takes a single named list which will be interpreted as its arguments. #' #' This is useful when you want to pass a function a row of data frame or #' array, and don't want to manually pull it apart in your function. #' #' @param flat function to splat #' @return a function #' @export #' @examples #' hp_per_cyl <- function(hp, cyl, ...) hp / cyl #' splat(hp_per_cyl)(mtcars[1,]) #' splat(hp_per_cyl)(mtcars) #' #' f <- function(mpg, wt, ...) data.frame(mw = mpg / wt) #' ddply(mtcars, .(cyl), splat(f)) splat <- function(flat) { function(args, ...) { do.call(flat, c(args, list(...))) } } plyr/R/round-any.r0000644000176000001440000000211112036015511013555 0ustar ripleyusers#' Round to multiple of any number. #' #' @param x numeric or date-time (POSIXct) vector to round #' @param accuracy number to round to; for POSIXct objects, a number of seconds #' @param f rounding function: \code{\link{floor}}, \code{\link{ceiling}} or #' \code{\link{round}} #' @keywords manip #' @export #' @examples #' round_any(135, 10) #' round_any(135, 100) #' round_any(135, 25) #' round_any(135, 10, floor) #' round_any(135, 100, floor) #' round_any(135, 25, floor) #' round_any(135, 10, ceiling) #' round_any(135, 100, ceiling) #' round_any(135, 25, ceiling) #' #' round_any(Sys.time() + 1:10, 5) #' round_any(Sys.time() + 1:10, 5, floor) #' round_any(Sys.time(), 3600) round_any <- function(x, accuracy, f = round) { UseMethod("round_any") } #' @S3method round_any numeric round_any.numeric <- function(x, accuracy, f = round) { f(x / accuracy) * accuracy } #' @S3method round_any POSIXct round_any.POSIXct <- function(x, accuracy, f = round) { tz <- format(x[1], "%Z") xr <- round_any(as.numeric(x), accuracy, f) as.POSIXct(xr, origin="1970-01-01 00:00.00 UTC", tz=tz) } plyr/R/rlply.r0000644000176000001440000000254512035607671013033 0ustar ripleyusers#' Replicate expression and return results in a list. #' #' Evalulate expression n times then combine results into a list #' #' This function runs an expression multiple times, and combines the #' result into a list. If there are no results, then this function will return #' a list of length 0 (\code{list()}). This function is equivalent to #' \code{\link{replicate}}, but will always return results as a list. #' #' #' @keywords manip #' @param .n number of times to evaluate the expression #' @param .expr expression to evaluate #' @param .progress name of the progress bar to use, see \code{\link{create_progress_bar}} #' @return list of results #' @export #' @references Hadley Wickham (2011). The Split-Apply-Combine Strategy for #' Data Analysis. Journal of Statistical Software, 40(1), 1-29. #' \url{http://www.jstatsoft.org/v40/i01/}. #' @examples #' mods <- rlply(100, lm(y ~ x, data=data.frame(x=rnorm(100), y=rnorm(100)))) #' hist(laply(mods, function(x) summary(x)$r.squared)) rlply <- function(.n, .expr, .progress = "none") { if (is.function(.expr)) { f <- .expr } else { f <- eval.parent(substitute(function() .expr)) } progress <- create_progress_bar(.progress) result <- vector("list", length = .n) progress$init(.n) on.exit(progress$term()) for(i in seq_len(.n)) { result[i] <- list(f()) progress$step() } result } plyr/R/revalue.r0000644000176000001440000000631212035565262013327 0ustar ripleyusers#' Replace specified values with new values, in a factor or character vector. #' #' If \code{x} is a factor, the named levels of the factor will be #' replaced with the new values. #' #' This function works only on character vectors and factors, but the #' related \code{mapvalues} function works on vectors of any type and factors, #' and instead of a named vector specifying the original and replacement values, #' it takes two separate vectors #' #' @param x factor or character vector to modify #' @param replace named character vector, with new values as values, and #' old values as names. #' @param warn_missing print a message if any of the old values are #' not actually present in \code{x} #' #' @seealso \code{\link{mapvalues}} to replace values with vectors of any type #' @export #' @examples #' x <- c("a", "b", "c") #' revalue(x, c(a = "A", c = "C")) #' revalue(x, c("a" = "A", "c" = "C")) #' #' y <- factor(c("a", "b", "c", "a")) #' revalue(y, c(a = "A", c = "C")) revalue <- function(x, replace = NULL, warn_missing = TRUE) { if (!is.null(x) && !is.factor(x) && !is.character(x)) { stop("x is not a factor or a character vector.") } mapvalues(x, from = names(replace), to = replace, warn_missing = warn_missing) } #' Replace specified values with new values, in a vector or factor. #' #' Item in \code{x} that match items \code{from} will be replaced by #' items in \code{to}, matched by position. For example, items in \code{x} that #' match the first element in \code{from} will be replaced by the first #' element of \code{to}. #' #' If \code{x} is a factor, the matching levels of the factor will be #' replaced with the new values. #' #' The related \code{revalue} function works only on character vectors #' and factors, but this function works on vectors of any type and factors. #' #' @param x the factor or vector to modify #' @param from a vector of the items to replace #' @param to a vector of replacement values #' @param warn_missing print a message if any of the old values are #' not actually present in \code{x} #' #' @seealso \code{\link{revalue}} to do the same thing but with a single #' named vector instead of two separate vectors. #' @export #' @examples #' x <- c("a", "b", "c") #' mapvalues(x, c("a", "c"), c("A", "C")) #' #' # Works on factors #' y <- factor(c("a", "b", "c", "a")) #' mapvalues(y, c("a", "c"), c("A", "C")) #' #' # Works on numeric vectors #' z <- c(1, 4, 5, 9) #' mapvalues(z, from = c(1, 5, 9), to = c(10, 50, 90)) mapvalues <- function(x, from, to, warn_missing = TRUE) { if (length(from) != length(to)) { stop("`from` and `to` vectors are not the same length.") } if (!is.atomic(x)) { stop("`x` must be an atomic vector.") } if (is.factor(x)) { # If x is a factor, call self but operate on the levels levels(x) <- mapvalues(levels(x), from, to) return(x) } mapidx <- match(x, from) mapidxNA <- is.na(mapidx) # index of items in `from` that were found in `x` from_found <- sort(unique(mapidx)) if (warn_missing && length(from_found) != length(from)) { message("The following `from` values were not present in `x`: ", paste(from[!(1:length(from) %in% from_found) ], collapse = ", ")) } x[!mapidxNA] <- to[mapidx[!mapidxNA]] x } plyr/R/rename.r0000644000176000001440000000145412034020705013120 0ustar ripleyusers#' Modify names by name, not position. #' #' @param x named object to modify #' @param replace named character vector, with new names as values, and #' old names as names. #' @param warn_missing print a message if any of the old names are #' not actually present in \code{x}. #' Note: x is not altered: To save the result, you need to copy the returned #' data into a variable. #' @export #' @importFrom stats setNames #' @examples #' x <- c("a" = 1, "b" = 2, d = 3, 4) #' # Rename column d to "c", updating the variable "x" with the result #' x <- rename(x, replace=c("d" = "c")) #' x #' # Rename column "disp" to "displacement" #' rename(mtcars, c("disp" = "displacement")) rename <- function(x, replace, warn_missing = TRUE) { names(x) <- revalue(names(x), replace, warn_missing = warn_missing) x } plyr/R/rdply.r0000644000176000001440000000244512035607702013015 0ustar ripleyusers#' Replicate expression and return results in a data frame. #' #' Evalulate expression n times then combine results into a data frame #' #' This function runs an expression multiple times, and combines the #' result into a data frame. If there are no results, then this function #' returns a data frame with zero rows and columns (\code{data.frame()}). #' This function is equivalent to \code{\link{replicate}}, but will always #' return results as a data frame. #' #' #' @keywords manip #' @param .n number of times to evaluate the expression #' @param .expr expression to evaluate #' @param .progress name of the progress bar to use, see \code{\link{create_progress_bar}} #' @return a data frame #' @export #' @references Hadley Wickham (2011). The Split-Apply-Combine Strategy for #' Data Analysis. Journal of Statistical Software, 40(1), 1-29. #' \url{http://www.jstatsoft.org/v40/i01/}. #' @examples #' rdply(20, mean(runif(100))) #' rdply(20, each(mean, var)(runif(100))) #' rdply(20, data.frame(x = runif(2))) rdply <- function(.n, .expr, .progress = "none") { if (is.function(.expr)) { f <- .expr } else { f <- eval.parent(substitute(function() .expr)) } res <- rlply(.n = .n, .expr = f, .progress = .progress) labels <- data.frame(.n = seq_len(.n)) list_to_dataframe(res, labels) } plyr/R/rbind-fill.r0000644000176000001440000001024112034575045013701 0ustar ripleyusers#' Combine data.frames by row, filling in missing columns. #' #' \code{rbind}s a list of data frames filling missing columns with NA. #' #' This is an enhancement to \code{\link{rbind}} that adds in columns #' that are not present in all inputs, accepts a list of data frames, and #' operates substantially faster. #' #' Column names and types in the output will appear in the order in which #' they were encountered. No checking is performed to ensure that each column #' is of consistent type in the inputs. #' #' @param ... input data frames to row bind together. The first argument can #' be a list of data frames, in which case all other arguments are ignored. #' @keywords manip #' @family binding functions #' @return a single data frame #' @export #' @examples #' rbind.fill(mtcars[c("mpg", "wt")], mtcars[c("wt", "cyl")]) rbind.fill <- function(...) { dfs <- list(...) if (length(dfs) == 0) return() if (is.list(dfs[[1]]) && !is.data.frame(dfs[[1]])) { dfs <- dfs[[1]] } if (length(dfs) == 0) return() if (length(dfs) == 1) return(dfs[[1]]) # Check that all inputs are data frames is_df <- vapply(dfs, is.data.frame, logical(1)) if (any(!is_df)) { stop("All inputs to rbind.fill must be data.frames", call. = FALSE) } # Calculate rows in output # Using .row_names_info directly is about 6 times faster than using nrow rows <- unlist(lapply(dfs, .row_names_info, 2L)) nrows <- sum(rows) # Generate output template output <- output_template(dfs, nrows) # Case of zero column inputs if (length(output) == 0) { return(as.data.frame(matrix(nrow = nrows, ncol = 0))) } # Compute start and length for each data frame pos <- matrix(c(cumsum(rows) - rows + 1, rows), ncol = 2) # Copy inputs into output for(i in seq_along(rows)) { rng <- seq(pos[i, 1], length = pos[i, 2]) df <- dfs[[i]] for(var in names(df)) { if (!is.matrix(output[[var]])) { if (is.factor(output[[var]]) && is.character(df[[var]])) { output[[var]] <- as.character(output[[var]]) } output[[var]][rng] <- df[[var]] } else { output[[var]][rng, ] <- df[[var]] } } } quickdf(output) } output_template <- function(dfs, nrows) { vars <- unique(unlist(lapply(dfs, base::names))) # ~ 125,000/s output <- vector("list", length(vars)) names(output) <- vars seen <- rep(FALSE, length(output)) names(seen) <- vars is_array <- seen is_matrix <- seen is_factor <- seen for(df in dfs) { matching <- intersect(names(df), vars[!seen]) for(var in matching) { value <- df[[var]] if (is.vector(value) && is.atomic(value)) { output[[var]] <- rep(NA, nrows) } else if (is.factor(value)) { output[[var]] <- factor(rep(NA, nrows), ordered = is.ordered(value)) is_factor[var] <- TRUE } else if (is.matrix(value)) { is_matrix[var] <- TRUE } else if (is.array(value)) { is_array[var] <- TRUE } else if (inherits(value, "POSIXt")) { output[[var]] <- as.POSIXct(rep(NA, nrows)) attr(output[[var]], "tzone") <- attr(value, "tzone") } else if (is.list(value)) { output[[var]] <- vector("list", nrows) } else { output[[var]] <- rep(NA, nrows) class(output[[var]]) <- class(value) attributes(output[[var]]) <- attributes(value) } } seen[matching] <- TRUE if (all(seen)) break # Quit as soon as all done } # Set up factors for(var in vars[is_factor]) { all <- unique(lapply(dfs, function(df) levels(df[[var]]))) output[[var]] <- factor(output[[var]], levels = unique(unlist(all)), exclude = NULL) } # Set up matrices for(var in vars[is_matrix]) { width <- unique(unlist(lapply(dfs, function(df) ncol(df[[var]])))) if (length(width) > 1) stop("Matrix variable ", var, " has inconsistent widths") vec <- rep(NA, nrows * width) output[[var]] <- array(vec, c(nrows, width)) } # Set up arrays for (var in vars[is_array]) { dims <- unique(unlist(lapply(dfs, function(df) dims(df[[var]])))) if (any(dims) > 1) { stop("rbind.fill can only work with 1d arrays") } output[[var]] <- rep(NA, nrows) } output } plyr/R/rbind-fill-matrix.r0000644000176000001440000000465712034573225015217 0ustar ripleyusers#' Bind matrices by row, and fill missing columns with NA. #' #' The matrices are bound together using their column names or the column #' indices (in that order of precedence.) Numeric columns may be converted to #' character beforehand, e.g. using format. If a matrix doesn't have #' colnames, the column number is used. Note that this means that a #' column with name \code{"1"} is merged with the first column of a matrix #' without name and so on. The returned matrix will always have column names. #' #' Vectors are converted to 1-column matrices. #' #' Matrices of factors are not supported. (They are anyways quite #' inconvenient.) You may convert them first to either numeric or character #' matrices. If a matrices of different types are merged, then normal #' covnersion precendence will apply. #' #' Row names are ignored. #' #' @param ... the matrices to rbind. The first argument can be a list of #' matrices, in which case all other arguments are ignored. #' @return a matrix with column names #' @author C. Beleites #' @seealso \code{\link[base]{rbind}}, \code{\link[base]{cbind}}, #' \code{\link[plyr]{rbind.fill}} #' @family binding functions #' @export #' @keywords manip #' @examples #' A <- matrix (1:4, 2) #' B <- matrix (6:11, 2) #' A #' B #' rbind.fill.matrix (A, B) #' #' colnames (A) <- c (3, 1) #' A #' rbind.fill.matrix (A, B) #' #' rbind.fill.matrix (A, 99) rbind.fill.matrix <- function(...) { matrices <- list(...) if (length(matrices) == 0) return() if (is.list(matrices[[1]]) && !is.matrix(matrices[[1]])) { matrices <- matrices[[1]] } ## check the arguments tmp <- unlist(lapply(matrices, is.factor)) if (any(tmp)) { stop("Input ", paste(which(tmp), collapse = ", "), " is a factor and ", "needs to be converted first to either numeric or character.") } matrices[] <- lapply(matrices, as.matrix) # Work out common column names lcols <- lapply(matrices, function(x) amv_dimnames(x)[[2]]) cols <- unique(unlist(lcols)) # Calculate rows in output rows <- unlist(lapply(matrices, nrow)) nrows <- sum(rows) # Generate output template output <- matrix(NA, nrow = nrows, ncol = length(cols)) colnames(output) <- cols # Compute start and length for each matrix pos <- matrix(c(cumsum(rows) - rows + 1, rows), ncol = 2) ## fill in the new matrix for(i in seq_along(rows)) { rng <- seq(pos[i, 1], length = pos[i, 2]) output[rng, lcols[[i]]] <- matrices[[i]] } output } plyr/R/raply.r0000644000176000001440000000323512035607714013013 0ustar ripleyusers#' Replicate expression and return results in a array. #' #' Evalulate expression n times then combine results into an array #' #' This function runs an expression multiple times, and combines the #' result into a data frame. If there are no results, then this function #' returns a vector of length 0 (\code{vector(0)}). #' This function is equivalent to \code{\link{replicate}}, but will always #' return results as a vector, matrix or array. #' #' @keywords manip #' @param .n number of times to evaluate the expression #' @param .expr expression to evaluate #' @param .progress name of the progress bar to use, see \code{\link{create_progress_bar}} #' @return if results are atomic with same type and dimensionality, a vector, matrix or array; otherwise, a list-array (a list with dimensions) #' @param .drop should extra dimensions of length 1 be dropped, simplifying the output. Defaults to \code{TRUE} #' @export #' @references Hadley Wickham (2011). The Split-Apply-Combine Strategy for #' Data Analysis. Journal of Statistical Software, 40(1), 1-29. #' \url{http://www.jstatsoft.org/v40/i01/}. #' @examples #' raply(100, mean(runif(100))) #' raply(100, each(mean, var)(runif(100))) #' #' raply(10, runif(4)) #' raply(10, matrix(runif(4), nrow=2)) #' #' # See the central limit theorem in action #' hist(raply(1000, mean(rexp(10)))) #' hist(raply(1000, mean(rexp(100)))) #' hist(raply(1000, mean(rexp(1000)))) raply <- function(.n, .expr, .progress = "none", .drop = TRUE) { if (is.function(.expr)) { f <- .expr } else { f <- eval.parent(substitute(function() .expr)) } res <- rlply(.n = .n, .expr = f, .progress = .progress) list_to_array(res, NULL, .drop) } plyr/R/r_ply.r0000644000176000001440000000222512035607722013006 0ustar ripleyusers#' Replicate expression and discard results. #' #' Evalulate expression n times then discard results #' #' This function runs an expression multiple times, discarding the results. #' This function is equivalent to \code{\link{replicate}}, but never returns #' anything #' #' @keywords manip #' @param .n number of times to evaluate the expression #' @param .expr expression to evaluate #' @param .progress name of the progress bar to use, see \code{\link{create_progress_bar}} #' @param .print automatically print each result? (default: \code{FALSE}) #' @export #' @references Hadley Wickham (2011). The Split-Apply-Combine Strategy for #' Data Analysis. Journal of Statistical Software, 40(1), 1-29. #' \url{http://www.jstatsoft.org/v40/i01/}. #' @examples #' r_ply(10, plot(runif(50))) #' r_ply(25, hist(runif(1000))) r_ply <- function(.n, .expr, .progress = "none", .print = FALSE) { if (is.function(.expr)) { f <- .expr } else { f <- eval.parent(substitute(function() .expr)) } progress <- create_progress_bar(.progress) progress$init(.n) on.exit(progress$term()) for(i in seq_len(.n)) { f() progress$step() } progress$term() } plyr/R/quote.r0000644000176000001440000001440612034020705013007 0ustar ripleyusers#' Quote variables to create a list of unevaluated expressions for later #' evaluation. #' #' This function is similar to \code{\link{~}} in that it is used to #' capture the name of variables, not their current value. This is used #' throughout plyr to specify the names of variables (or more complicated #' expressions). #' #' Similar tricks can be performed with \code{\link{substitute}}, but when #' functions can be called in multiple ways it becomes increasingly tricky #' to ensure that the values are extracted from the correct frame. Substitute #' tricks also make it difficult to program against the functions that use #' them, while the \code{quoted} class provides #' \code{as.quoted.character} to convert strings to the appropriate #' data structure. #' #' @param ... unevaluated expressions to be recorded. Specify names if you #' want the set the names of the resultant variables #' @param .env environment in which unbound symbols in \code{...} should be #' evaluated. Defaults to the environment in which \code{.} was executed. #' @return list of symbol and language primitives #' @aliases . quoted is.quoted #' @export . is.quoted #' @rdname quoted #' @examples #' .(a, b, c) #' .(first = a, second = b, third = c) #' .(a ^ 2, b - d, log(c)) #' as.quoted(~ a + b + c) #' as.quoted(a ~ b + c) #' as.quoted(c("a", "b", "c")) #' #' # Some examples using ddply - look at the column names #' ddply(mtcars, "cyl", each(nrow, ncol)) #' ddply(mtcars, ~ cyl, each(nrow, ncol)) #' ddply(mtcars, .(cyl), each(nrow, ncol)) #' ddply(mtcars, .(log(cyl)), each(nrow, ncol)) #' ddply(mtcars, .(logcyl = log(cyl)), each(nrow, ncol)) #' ddply(mtcars, .(vs + am), each(nrow, ncol)) #' ddply(mtcars, .(vsam = vs + am), each(nrow, ncol)) . <- function(..., .env = parent.frame()) { structure(as.list(match.call()[-1]), env = .env, class="quoted") } is.quoted <- function(x) inherits(x, "quoted") #' Print quoted variables. #' #' Display the \code{\link{str}}ucture of quoted variables #' #' @keywords internal #' @S3method print quoted #' @method print quoted print.quoted <- function(x, ...) str(x) #' Compute names of quoted variables. #' #' Figure out names of quoted variables, using specified names if they exist, #' otherwise converting the values to character strings. This may create #' variable names that can only be accessed using \code{``}. #' #' @keywords internal #' @S3method names quoted #' @method names quoted names.quoted <- function(x) { deparse2 <- function(x) paste(deparse(x), collapse = "") part_names <- unlist(lapply(x, deparse2)) user_names <- names(unclass(x)) if (!is.null(user_names)) { part_names[user_names != ""] <- user_names[user_names != ""] } unname(part_names) } #' Evaluate a quoted list of variables. #' #' Evaluates quoted variables in specified environment #' #' @return a list #' @keywords internal #' @param expr quoted object to evalution #' @param try if TRUE, return \code{NULL} if evaluation unsuccesful #' @export eval.quoted <- function(exprs, envir = NULL, enclos = NULL, try = FALSE) { if (is.numeric(exprs)) return(envir[exprs]) if (!is.null(envir) && !is.list(envir) && !is.environment(envir)) { stop("envir must be either NULL, a list, or an environment.") } qenv <- if (is.quoted(exprs)) attr(exprs, "env") else parent.frame() if (is.null(envir)) envir <- qenv if (is.data.frame(envir) && is.null(enclos)) enclos <- qenv if (try) { results <- lapply(exprs, failwith(NULL, eval, quiet = TRUE), envir = envir, enclos = enclos) } else { results <- lapply(exprs, eval, envir = envir, enclos = enclos) } names(results) <- names(exprs) results } #' Convert input to quoted variables. #' #' Convert characters, formulas and calls to quoted .variables #' #' This method is called by default on all plyr functions that take a #' \code{.variables} argument, so that equivalent forms can be used anywhere. #' #' Currently conversions exist for character vectors, formulas and #' call objects. #' #' @return a list of quoted variables #' @seealso \code{\link{.}} #' @param x input to quote #' @param env environment in which unbound symbols in expression should be #' evaluated. Defaults to the environment in which \code{as.quoted} was #' executed. #' @export #' @examples #' as.quoted(c("a", "b", "log(d)")) #' as.quoted(a ~ b + log(d)) as.quoted <- function(x, env = parent.frame()) UseMethod("as.quoted") #' @S3method as.quoted call as.quoted.call <- function(x, env = parent.frame()) { structure(as.list(x)[-1], env = env, class = "quoted") } #' @S3method as.quoted character as.quoted.character <- function(x, env = parent.frame()) { structure( lapply(x, function(x) parse(text = x)[[1]]), env = env, class = "quoted" ) } #' @S3method as.quoted numeric as.quoted.numeric <- function(x, env = parent.frame()) { structure(x, env = env, class = c("quoted", "numeric")) } #' @S3method as.quoted formula as.quoted.formula <- function(x, env = parent.frame()) { simplify <- function(x) { if (length(x) == 2 && x[[1]] == as.name("~")) { return(simplify(x[[2]])) } if (length(x) < 3) return(list(x)) op <- x[[1]]; a <- x[[2]]; b <- x[[3]] if (op == as.name("+") || op == as.name("*") || op == as.name("~")) { c(simplify(a), simplify(b)) } else if (op == as.name("-")) { c(simplify(a), bquote(-.(x), list(x=simplify(b)))) } else { list(x) } } structure(simplify(x), env = env, class = "quoted") } #' @S3method as.quoted quoted as.quoted.quoted <- function(x, env = parent.frame()) x #' @S3method as.quoted NULL as.quoted.NULL <- function(x, env = parent.frame()) { structure(list(), env = env, class = "quoted") } #' @S3method as.quoted name as.quoted.name <- function(x, env = parent.frame()) { structure(list(x), env = env, class = "quoted") } #' @S3method as.quoted factor as.quoted.factor <- function(x, env = parent.frame()) { as.quoted(as.character(x), env) } #' @S3method c quoted c.quoted <- function(..., recursive = FALSE) { structure(NextMethod("c"), class = "quoted", env = attr(list(...)[[1]], "env")) } #' @S3method [ quoted "[.quoted" <- function(x, i, ...) { structure(NextMethod("["), env = attr(x, "env"), class = "quoted") } #' Is a formula? #' Checks if argument is a formula #' #' @keywords internal #' @export is.formula <- function(x) inherits(x, "formula") plyr/R/quickdf.r0000644000176000001440000000133012034574010013273 0ustar ripleyusers#' Quick data frame. #' #' Experimental version of \code{\link{as.data.frame}} that converts a #' list to a data frame, but doesn't do any checks to make sure it's a #' valid format. Much faster. #' #' @param list list to convert to data frame #' @keywords internal #' @export quickdf <- function(list) { rows <- unique(unlist(lapply(list, NROW))) stopifnot(length(rows) == 1) names(list) <- make_names(list, "X") class(list) <- "data.frame" attr(list, "row.names") <- c(NA_integer_, -rows) list } make_names <- function(x, prefix = "X") { nm <- names(x) if (is.null(nm)) { nm <- rep.int("", length(x)) } n <- sum(nm == "", na.rm = TRUE) nm[nm == ""] <- paste(prefix, seq_len(n), sep = "") nm } plyr/R/progress.r0000644000176000001440000001224012057431371013522 0ustar ripleyusers#' Create progress bar. #' #' Create progress bar object from text string. #' #' Progress bars give feedback on how apply step is proceeding. This #' is mainly useful for long running functions, as for short functions, the #' time taken up by splitting and combining may be on the same order (or #' longer) as the apply step. Additionally, for short functions, the time #' needed to update the progress bar can significantly slow down the process. #' For the trivial examples below, using the tk progress bar slows things down #' by a factor of a thousand. #' #' Note the that progress bar is approximate, and if the time taken by #' individual function applications is highly non-uniform it may not be very #' informative of the time left. #' #' There are currently four types of progress bar: "none", "text", "tk", and #' "win". See the individual documentation for more details. In plyr #' functions, these can either be specified by name, or you can create the #' progress bar object yourself if you want more control over its apperance. #' See the examples. #' #' @param name type of progress bar to create #' @param ... other arguments passed onto progress bar function #' @seealso \code{\link{progress_none}}, \code{\link{progress_text}}, \code{\link{progress_tk}}, \code{\link{progress_win}} #' @keywords utilities #' @export #' @examples #' # No progress bar #' l_ply(1:100, identity, .progress = "none") #' \dontrun{ #' # Use the Tcl/Tk interface #' l_ply(1:100, identity, .progress = "tk") #' } #' # Text-based progress (|======|) #' l_ply(1:100, identity, .progress = "text") #' # Choose a progress character, run a length of time you can see #' l_ply(1:10000, identity, .progress = progress_text(char = ".")) create_progress_bar <- function(name = "none", ...) { if (!is.character(name)) return(name) name <- paste("progress", name, sep="_") if (!exists(name, mode = "function")) { warning("Cannot find progress bar ", name, call. = FALSE) progress_none() } else { match.fun(name)(...) } } #' Null progress bar #' #' A progress bar that does nothing #' #' This the default progress bar used by plyr functions. It's very simple to #' understand - it does nothing! #' #' @keywords internal #' @family progress bars #' @export #' @examples #' l_ply(1:100, identity, .progress = "none") progress_none <- function() { list( init = function(x) {}, step = function() {}, term = function() {} ) } #' Text progress bar. #' #' A textual progress bar #' #' This progress bar displays a textual progress bar that works on all #' platforms. It is a thin wrapper around the built-in #' \code{\link{setTxtProgressBar}} and can be customised in the same way. #' #' @param style style of text bar, see Details section of \code{\link{txtProgressBar}} #' @param ... other arugments passed on to \code{\link{txtProgressBar}} #' @family progress bars #' @export #' @examples #' l_ply(1:100, identity, .progress = "text") #' l_ply(1:100, identity, .progress = progress_text(char = "-")) progress_text <- function(style = 3, ...) { n <- 0 txt <- NULL list( init = function(x) { txt <<- txtProgressBar(max = x, style = style, ...) setTxtProgressBar(txt, 0) }, step = function() { n <<- n + 1 setTxtProgressBar(txt, n) }, term = function() close(txt) ) } #' Graphical progress bar, powered by Tk. #' #' A graphical progress bar displayed in a Tk window #' #' This graphical progress will appear in a separate window. #' #' @param title window title #' @param label progress bar label (inside window) #' @param ... other arguments passed on to \code{\link[tcltk]{tkProgressBar}} #' @seealso \code{\link[tcltk]{tkProgressBar}} for the function that powers this progress bar #' @family progress bars #' @export #' @examples #' \dontrun{ #' l_ply(1:100, identity, .progress = "tk") #' l_ply(1:100, identity, .progress = progress_tk(width=400)) #' l_ply(1:100, identity, .progress = progress_tk(label="")) #' } progress_tk <- function(title = "plyr progress", label = "Working...", ...) { stopifnot(require("tcltk", quietly = TRUE)) n <- 0 tk <- NULL list( init = function(x) { tk <<- tkProgressBar(max = x, title = title, label = label, ...) setTkProgressBar(tk, 0) }, step = function() { n <<- n + 1 setTkProgressBar(tk, n) }, term = function() close(tk) ) } #' Graphical progress bar, powered by Windows. #' #' A graphical progress bar displayed in a separate window #' #' This graphical progress only works on Windows. #' #' @param title window title #' @param ... other arguments passed on to \code{winProgressBar} #' @seealso \code{winProgressBar} for the function that powers this progress bar #' @export #' @family progress bars #' @examples #' if(exists("winProgressBar")) { #' l_ply(1:100, identity, .progress = "win") #' l_ply(1:100, identity, .progress = progress_win(title="Working...")) #' } progress_win <- function(title = "plyr progress", ...) { n <- 0 win <- NULL list( init = function(x) { win <<- winProgressBar(max = x, title = title, ...) setWinProgressBar(win, 0) }, step = function() { n <<- n + 1 setWinProgressBar(win, n) }, term = function() close(win) ) } plyr/R/progress-time.r0000644000176000001440000000400712034606623014457 0ustar ripleyusers#' Text progress bar with time. #' #' A textual progress bar that estimates time remaining. It displays the #' estimated time remaining and, when finished, total duration. #' #' @family progress bars #' @export #' @examples #' l_ply(1:100, function(x) Sys.sleep(.01), .progress = "time") progress_time <- function() { n <- 0 txt <- NULL list( init = function(x) { txt <<- txtTimerBar(x) setTxtProgressBar(txt, 0) }, step = function() { n <<- n + 1 setTxtProgressBar(txt, n) }, term = function() close(txt) ) } txtTimerBar <- function(n = 1) { start <- .last_update_time <- proc.time()[3] times <- numeric(n) value <- NULL killed <- FALSE width <- getOption("width") - nchar('||100% ~ 999.9 h remaining.') update <- function(i) { if (i == 0) return() value <<- i times[i] <- proc.time()[3] - start avg <- times[i] / i time_left <- (n - i) * avg nbars <- trunc(i / n * width) cat_line("|", str_rep("=", nbars), str_rep(" ", width - nbars), "|", format(i / n * 100, width = 3), "% ~", show_time(time_left), " remaining") } getVal <- function() value kill <- function(){ if (killed) return() killed <<- TRUE if (value == n) { cat_line("|", str_rep("=", width), "|100%") cat("Completed after", show_time(proc.time()[3] - start), "\n") } else { cat("Killed after", show_time(proc.time()[3] - start), "\n") } } cat_line("|", str_rep(" ", width), "| 0%") structure( list(getVal = getVal, up = update, kill = kill), class = "txtProgressBar") } show_time <- function(x) { if (x < 60) { paste(round(x), "s") } else if (x < 60 * 60) { paste(round(x / 60), "m") } else { paste(round(x / (60 * 60)), "h") } } cat_line <- function(...) { msg <- paste(..., sep = "", collapse = "") gap <- max(c(0, getOption("width") - nchar(msg, "width"))) cat("\r", msg, rep.int(" ", gap), sep = "") flush.console() } str_rep <- function(x, i) { paste(rep.int(x, i), collapse = "") } plyr/R/plyr.r0000644000176000001440000000531512034616554012654 0ustar ripleyusers#' plyr: the split-apply-combine paradigm for R. #' #' The plyr package is a set of clean and consistent tools that implement the #' split-apply-combine pattern in R. This is an extremely common pattern in #' data analysis: you solve a complex problem by breaking it down into small #' pieces, doing something to each piece and then combining the results back #' together again. #' #' The plyr functions are named according to what sort of data structure they #' split up and what sort of data structure they return: #' #' \describe{ #' \item{a}{array} #' \item{l}{list} #' \item{d}{data.frame} #' \item{m}{multiple inputs} #' \item{r}{repeat multiple times} #' \item{_}{nothing} #' } #' #' So \code{\link{ddply}} takes a data frame as input and returns a data frame #' as output, and \code{\link{l_ply}} takes a list as input and returns nothing #' as output. #' #' @section Row names: #' #' By design, no plyr function will preserve row names - in general it is too #' hard to know what should be done with them for many of the operations #' supported by plyr. If you want to preserve row names, use #' \code{\link{name_rows}} to convert them into an explicit column in your #' data frame, perform the plyr operations, and then use \code{\link{name_rows}} #' again to convert the column back into row names. #' #' @section Helpers: #' #' Plyr also provides a set of helper functions for common data analysis #' problems: #' #' \itemize{ #' \item \code{\link{arrange}}: re-order the rows of a data frame by #' specifying the columns to order by #' \item \code{\link{mutate}}: add new columns or modifying existing columns, #' like \code{\link{transform}}, but new columns can refer to other columns #' that you just created. #' \item \code{\link{summarise}}: like \code{\link{mutate}} but create a #' new data frame, not preserving any columns in the old data frame. #' #' \item \code{\link{join}}: an adapation of \code{\link{merge}} which is #' more similar to SQL, and has a much faster implementation if you only #' want to find the first match. #' \item \code{\link{match_df}}: a version of \code{\link{join}} that instead #' of returning the two tables combined together, only returns the rows #' in the first table that match the second. #' #' \item \code{\link{colwise}}: make any function work colwise on a dataframe #' \item \code{\link{rename}}: easily rename columns in a data frame #' \item \code{\link{round_any}}: round a number to any degree of precision #' \item \code{\link{count}}: quickly count unique combinations and return #' return as a data frame. #' } #' #' @docType package #' @name plyr NULL .onUnload <- function (libpath) { library.dynam.unload("plyr", libpath) } plyr/R/parallel.r0000644000176000001440000000060612035566223013456 0ustar ripleyuserssetup_parallel <- function() { if (!require("foreach")) { stop("foreach package required for parallel plyr operation", call. = FALSE) } if (getDoParWorkers() == 1) { warning("No parallel backend registered", call. = TRUE) } } parallel_fe <- function(n, options) { i <- seq_len(n) fe_call <- as.call(c(list(as.name("foreach"), i = i), options)) eval(fe_call) } plyr/R/name-rows.r0000644000176000001440000000161112034615221013557 0ustar ripleyusers#' Toggle row names between explicit and implicit. #' #' Plyr functions ignore row names, so this function provides a way to preserve #' them by converting them to an explicit column in the data frame. After the #' plyr operation, you can then apply \code{name_rows} again to convert back #' from the explicit column to the implicit \code{rownames}. #' #' @param df a data.frame, with either \code{rownames}, or a column called #' \code{.rownames}. #' @export #' @examples #' name_rows(mtcars) #' name_rows(name_rows(mtcars)) #' #' df <- data.frame(a = sample(10)) #' arrange(df, a) #' arrange(name_rows(df), a) #' name_rows(arrange(name_rows(df), a)) name_rows <- function(df) { stopifnot(is.data.frame(df)) rn_col <- !is.null(df$.rownames) if (rn_col) { rownames(df) <- df$.rownames df$.rownames <- NULL } else { df$.rownames <- rownames(df) rownames(df) <- NULL } df } plyr/R/mutate.r0000644000176000001440000000265212035565262013166 0ustar ripleyusers#' Mutate a data frame by adding new or replacing existing columns. #' #' This function is very similar to \code{\link{transform}} but it executes #' the transformations iteratively so that later transformations can use the #' columns created by earlier transformations. Like transform, unnamed #' components are silently dropped. #' #' Mutate seems to be considerably faster than transform for large data #' frames. #' #' @param .data the data frame to transform #' @param ... named parameters giving definitions of new columns. #' @seealso \code{\link{subset}}, \code{\link{summarise}}, #' \code{\link{arrange}}. For another somewhat different approach to #' solving the same problem, see \code{\link{within}}. #' @export #' @examples #' # Examples from transform #' mutate(airquality, Ozone = -Ozone) #' mutate(airquality, new = -Ozone, Temp = (Temp - 32) / 1.8) #' #' # Things transform can't do #' mutate(airquality, Temp = (Temp - 32) / 1.8, OzT = Ozone / Temp) #' #' # mutate is rather faster than transform #' system.time(transform(baseball, avg_ab = ab / g)) #' system.time(mutate(baseball, avg_ab = ab / g)) mutate <- function(.data, ...) { stopifnot(is.data.frame(.data) || is.list(.data) || is.environment(.data)) cols <- as.list(substitute(list(...))[-1]) cols <- cols[names(cols) != ""] # Silently drop unnamed columns for(col in names(cols)) { .data[[col]] <- eval(cols[[col]], .data, parent.frame()) } .data } plyr/R/mlply.r0000644000176000001440000000156112035653743013024 0ustar ripleyusers#' Call function with arguments in array or data frame, returning a list. #' #' Call a multi-argument function with values taken from columns of an #' data frame or array, and combine results into a list. #' #' @template ply #' @template m- #' @template -l #' @export #' @examples #' mlply(cbind(1:4, 4:1), rep) #' mlply(cbind(1:4, times = 4:1), rep) #' #' mlply(cbind(1:4, 4:1), seq) #' mlply(cbind(1:4, length = 4:1), seq) #' mlply(cbind(1:4, by = 4:1), seq, to = 20) mlply <- function(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL) { if (is.matrix(.data) & !is.list(.data)) .data <- .matrix_to_df(.data) f <- splat(.fun) alply(.data = .data, .margins = 1, .fun = f, ..., .expand = .expand, .progress = .progress, .inform = .inform, .parallel = .parallel, .paropts = .paropts) } plyr/R/mdply.r0000644000176000001440000000165112035653720013007 0ustar ripleyusers#' Call function with arguments in array or data frame, returning a data frame. #' #' Call a multi-argument function with values taken from columns of an #' data frame or array, and combine results into a data frame #' #' @template ply #' @template m- #' @template -d #' @export #' @examples #' mdply(data.frame(mean = 1:5, sd = 1:5), rnorm, n = 2) #' mdply(expand.grid(mean = 1:5, sd = 1:5), rnorm, n = 2) #' mdply(cbind(mean = 1:5, sd = 1:5), rnorm, n = 5) #' mdply(cbind(mean = 1:5, sd = 1:5), as.data.frame(rnorm), n = 5) mdply <- function(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL) { if (is.matrix(.data) & !is.list(.data)) .data <- .matrix_to_df(.data) f <- splat(.fun) adply(.data = .data, .margins = 1, .fun = f, ..., .expand = .expand, .progress = .progress, .inform = .inform, .parallel = .parallel, .paropts = .paropts) } plyr/R/match-df.r0000644000176000001440000000337012034576574013357 0ustar ripleyusers#' Extract matching rows of a data frame. #' #' Match works in the same way as join, but instead of return the combined #' dataset, it only returns the matching rows from the first dataset. This is #' particularly useful when you've summarised the data in some way #' and want to subset the original data by a characteristic of the subset. #' #' \code{match_df} shares the same semantics as \code{\link{join}}, not #' \code{\link{match}}: #' #' \itemize{ #' \item the match criterion is \code{==}, not \code{\link{identical}}). #' \item it doesn't work for columns that are not atomic vectors #' \item if there are no matches, the row will be omitted' #' } #' #' @param x data frame to subset. #' @param y data frame defining matching rows. #' @param on variables to match on - by default will use all variables common #' to both data frames. #' @return a data frame #' @seealso \code{\link{join}} to combine the columns from both x and y #' and \code{\link{match}} for the base function selecting matching items #' @export #' @examples #' # count the occurrences of each id in the baseball dataframe, then get the subset with a freq >25 #' longterm <- subset(count(baseball, "id"), freq > 25) #' # longterm #' # id freq #' # 30 ansonca01 27 #' # 48 baineha01 27 #' # ... #' # Select only rows from these longterm players from the baseball dataframe #' # (match would default to match on shared column names, but here was explicitly set "id") #' bb_longterm <- match_df(baseball, longterm, on="id") #' bb_longterm[1:5,] match_df <- function(x, y, on = NULL) { if (is.null(on)) { on <- intersect(names(x), names(y)) message("Matching on: ", paste(on, collapse = ", ")) } keys <- join.keys(x, y, on) x[keys$x %in% keys$y, , drop = FALSE] } plyr/R/maply.r0000644000176000001440000000157412035653710013007 0ustar ripleyusers#' Call function with arguments in array or data frame, returning an array. #' #' Call a multi-argument function with values taken from columns of an #' data frame or array, and combine results into an array #' #' @template ply #' @template m- #' @template -a #' @export #' @examples #' maply(cbind(mean = 1:5, sd = 1:5), rnorm, n = 5) #' maply(expand.grid(mean = 1:5, sd = 1:5), rnorm, n = 5) #' maply(cbind(1:5, 1:5), rnorm, n = 5) maply <- function(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL) { if (is.matrix(.data) & !is.list(.data)) .data <- .matrix_to_df(.data) f <- splat(.fun) aaply(.data = .data, .margins = 1, .fun = f, ..., .expand = .expand, .progress = .progress, .inform = .inform, .parallel = .parallel, .paropts = .paropts, .drop = .drop) } plyr/R/m_ply.r0000644000176000001440000000133412035653700012776 0ustar ripleyusers#' Call function with arguments in array or data frame, discarding results. #' #' Call a multi-argument function with values taken from columns of an #' data frame or array, and discard results into a list. #' #' @template ply #' @template m- #' @template -_ #' @export m_ply <- function(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .print = FALSE, .parallel = FALSE, .paropts = NULL) { if (is.matrix(.data) & !is.list(.data)) .data <- .matrix_to_df(.data) f <- splat(.fun) a_ply(.data = .data, .margins = 1, .fun = f, ..., .expand = .expand, .progress = .progress, .inform = .inform, .print = .print, .parallel = .parallel, .paropts = .paropts) } plyr/R/loop-apply.r0000644000176000001440000000061012034020705013736 0ustar ripleyusers#' Loop apply #' #' An optimised version of lapply for the special case of operating on #' \code{seq_len(n)} #' #' @param n length of sequence #' @param f function to apply to each integer #' @param env environment in which to evaluate function #' @useDynLib plyr #' @keywords internal manip loop_apply <- function(n, f, env = parent.frame()) { .Call("loop_apply", as.integer(n), f, env) } plyr/R/llply.r0000644000176000001440000000462712035653073013025 0ustar ripleyusers#' Split list, apply function, and return results in a list. #' #' For each element of a list, apply function, keeping results as a list. #' #' \code{llply} is equivalent to \code{\link{lapply}} except that it will #' preserve labels and can display a progress bar. #' #' @template ply #' @template l- #' @template -l #' @export #' @examples #' llply(llply(mtcars, round), table) #' llply(baseball, summary) #' # Examples from ?lapply #' x <- list(a = 1:10, beta = exp(-3:3), logic = c(TRUE,FALSE,FALSE,TRUE)) #' #' llply(x, mean) #' llply(x, quantile, probs = 1:3/4) llply <- function(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL) { if (is.null(.fun)) return(as.list(.data)) if (is.character(.fun) || is.list(.fun)) .fun <- each(.fun) if (!is.function(.fun)) stop(".fun is not a function.") if (!inherits(.data, "split")) { pieces <- as.list(.data) # This special case can be done much faster with lapply, so do it. fast_path <- .progress == "none" && !.inform && !.parallel if (fast_path) { return(structure(lapply(pieces, .fun, ...), dim = dim(pieces))) } } else { pieces <- .data } n <- length(pieces) if (n == 0) return(list()) if (.parallel && .progress != "none") { message("Progress disabled when using parallel plyr") .progress <- "none" } progress <- create_progress_bar(.progress) progress$init(n) on.exit(progress$term()) result <- vector("list", n) do.ply <- function(i) { piece <- pieces[[i]] # Display informative error messages, if desired if (.inform) { res <- try(.fun(piece, ...)) if (inherits(res, "try-error")) { piece <- paste(capture.output(print(piece)), collapse = "\n") stop("with piece ", i, ": \n", piece, call. = FALSE) } } else { res <- .fun(piece, ...) } progress$step() res } if (.parallel) { setup_parallel() i <- seq_len(n) fe_call <- as.call(c(list(as.name("foreach"), i = i), .paropts)) fe <- eval(fe_call) result <- fe %dopar% do.ply(i) } else { result <- loop_apply(n, do.ply) } attributes(result)[c("split_type", "split_labels")] <- attributes(pieces)[c("split_type", "split_labels")] names(result) <- names(pieces) # Only set dimension if not null, otherwise names are removed if (!is.null(dim(pieces))) { dim(result) <- dim(pieces) } result } plyr/R/list-to-vector.r0000644000176000001440000000102612034020705014537 0ustar ripleyusers#' List to vector. #' #' Reduce/simplify a list of homogenous objects to a vector #' #' @param res list of input data #' @keywords internal #' @family list simplification functions list_to_vector <- function(res) { n <- length(res) if (n == 0) return(vector()) if (n == 1) return(res[[1]]) atomic <- sapply(res, is.atomic) if (all(atomic)) { numeric <- all(unlist(lapply(res, is.numeric))) classes <- unique(lapply(res, class)) if (numeric || length(classes) == 1) { res <- unlist(res) } } res } plyr/R/list-to-dataframe.r0000644000176000001440000000346212034573275015206 0ustar ripleyusers#' List to data frame. #' #' Reduce/simplify a list of homogenous objects to a data frame. #' All \code{NULL} entries are removed. Remaining entries must be all atomic #' or all data frames. #' #' @family list simplification functions #' @param res list of input data #' @param labels a data frame of labels, one row for each element of res #' @keywords internal list_to_dataframe <- function(res, labels = NULL) { null <- vapply(res, is.null, logical(1)) res <- res[!null] if (length(res) == 0) return(data.frame()) if (!is.null(labels)) { stopifnot(nrow(labels) == length(null)) labels <- labels[!null, , drop = FALSE] } if (is.null(labels) && !is.null(names(res))) { labels <- data.frame(.id = names(res), stringsAsFactors = FALSE) } # Figure out how to turn elements into a data frame atomic <- unlist(lapply(res, is.atomic)) df <- unlist(lapply(res, is.data.frame)) mat <- unlist(lapply(res, is.matrix)) if (all(mat)) { resdf <- as.data.frame(rbind.fill.matrix(res)) rows <- unlist(lapply(res, NROW)) } else if (all(atomic)) { nrow <- length(res) ncol <- unique(unlist(lapply(res, length))) if (length(ncol) != 1) stop("Results do not have equal lengths") vec <- unname(do.call("c", res)) resdf <- quickdf(unname(split(vec, rep(seq_len(ncol), nrow)))) names(resdf) <- make_names(res[[1]], "V") rows <- rep(1, length(nrow)) } else if (all(df)) { resdf <- rbind.fill(res) rows <- unlist(lapply(res, NROW)) } else { stop("Results must be all atomic, or all data frames") } if(is.null(labels)) return(unrowname(resdf)) # Add labels to results names(labels) <- make_names(labels, "X") cols <- setdiff(names(labels), names(resdf)) labels <- labels[rep(1:nrow(labels), rows), cols, drop = FALSE] unrowname(cbind(labels, resdf)) } plyr/R/list-to-array.r0000644000176000001440000000373612034610754014376 0ustar ripleyusers#' List to array. #' #' Reduce/simplify a list of homogenous objects to an array #' #' @param res list of input data #' @param labels a data frame of labels, one row for each element of res #' @param .drop should extra dimensions be dropped (TRUE) or preserved (FALSE) #' @family list simplification functions #' @keywords internal list_to_array <- function(res, labels = NULL, .drop = FALSE) { if (length(res) == 0) return(vector()) n <- length(res) atomic <- sapply(res, is.atomic) if (all(atomic) || all(!atomic)) { dlength <- unique.default(llply(res, dims)) if (length(dlength) != 1) stop("Results must have the same number of dimensions.") dims <- unique(do.call("rbind", llply(res, amv_dim))) if (is.null(dims)) stop("Results must have one or more dimensions.", call. = FALSE) if (nrow(dims) != 1) stop("Results must have the same dimensions.", call. = FALSE) res_dim <- amv_dim(res[[1]]) res_labels <- amv_dimnames(res[[1]]) res_index <- expand.grid(res_labels) res <- unlist(res, use.names = FALSE, recursive = FALSE) } else { stop("Results must have compatible types.") } if (is.null(labels)) { labels <- data.frame(X = seq_len(n)) in_labels <- list(NULL) in_dim <- n } else { in_labels <- lapply(labels, function(x) if(is.factor(x)) levels(x) else sort(unique(x))) in_dim <- sapply(in_labels, length) } # Work out where each result should go in the new array index_old <- rep(id(rev(labels)), each = nrow(res_index)) index_new <- rep(id(rev(res_index)), nrow(labels)) index <- (index_new - 1) * prod(in_dim) + index_old out_dim <- unname(c(in_dim, res_dim)) out_labels <- c(in_labels, res_labels) n <- prod(out_dim) if (length(index) < n) { overall <- match(1:n, index, nomatch = NA) } else { overall <- order(index) } out_array <- res[overall] dim(out_array) <- out_dim dimnames(out_array) <- out_labels if (.drop) reduce_dim(out_array) else out_array } plyr/R/liply.r0000644000176000001440000000371512035607646013024 0ustar ripleyusers#' Experimental iterator based version of llply. #' #' Because iterators do not have known length, \code{liply} starts by #' allocating an output list of length 50, and then doubles that length #' whenever it runs out of space. This gives O(n ln n) performance rather #' than the O(n ^ 2) performance from the naive strategy of growing the list #' each time. #' #' @keywords manip #' @param .iterator iterator object #' @param .fun function to apply to each piece #' @param ... other arguments passed on to \code{.fun} #' @export #' @examples #' if(require("iterators")) { #' system.time(dlply(baseball, "id", summarise, mean_rbi = mean(rbi))) #' system.time({ #' baseball_id <- isplit2(baseball, baseball$id) #' liply(baseball_id, summarise, mean_rbi = mean(rbi, na.rm = TRUE)) #' }) #' # Iterators get used up: #' liply(baseball_id, summarise, mean_rbi = mean(rbi, na.rm = TRUE)) #' } liply <- function(.iterator, .fun = NULL, ...) { stopifnot(inherits(.iterator, "iter")) if (is.null(.fun)) return(as.list(.iterator)) iterator <- itertools::ihasNext(.iterator) if (is.character(.fun)) .fun <- each(.fun) if (!is.function(.fun)) stop(".fun is not a function.") result <- vector("list", 50) i <- 0 while(itertools::hasNext(iterator)) { piece <- iterators::nextElem(iterator) res <- .fun(piece, ...) # Double length of vector when necessary. Gives O(n ln n) performance # instead of naive O(n^2) i <- i + 1 if (i > length(result)) { length(result) <- length(result) * 2 } if (!is.null(res)) result[[i]] <- res } length(result) <- i result } #' Split iterator that returns values, not indices. #' #' @keywords internal #' @export isplit2 <- function (x, f, drop = FALSE, ...) { it <- iterators::isplit(seq_len(nrow(x)), f, drop = drop, ...) nextEl <- function() { i <- iterators::nextElem(it) x[i$value, , drop = FALSE] } structure(list(nextElem = nextEl), class = c("abstractiter", "iter")) } plyr/R/ldply.r0000644000176000001440000000114612035653665013015 0ustar ripleyusers#' Split list, apply function, and return results in a data frame. #' #' For each element of a list, apply function then combine results into a data #' frame. #' #' @template ply #' @template l- #' @template -d #' @export ldply <- function(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL) { if (!inherits(.data, "split")) .data <- as.list(.data) res <- llply(.data = .data, .fun = .fun, ..., .progress = .progress, .inform = .inform, .parallel = .parallel, .paropts = .paropts) list_to_dataframe(res, attr(.data, "split_labels")) } plyr/R/laply.r0000644000176000001440000000230412043515037012774 0ustar ripleyusers#' Split list, apply function, and return results in an array. #' #' For each element of a list, apply function then combine results into an #' array. #' #' \code{laply} is similar in spirit to \code{\link{sapply}} except #' that it will always return an array, and the output is transposed with #' respect \code{sapply} - each element of the list corresponds to a row, #' not a column. #' #' @template ply #' @template l- #' @template -a #' @export #' @examples #' laply(baseball, is.factor) #' # cf #' ldply(baseball, is.factor) #' colwise(is.factor)(baseball) #' #' laply(seq_len(10), identity) #' laply(seq_len(10), rep, times = 4) #' laply(seq_len(10), matrix, nrow = 2, ncol = 2) laply <- function(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL) { if (is.character(.fun)) .fun <- do.call("each", as.list(.fun)) if (!is.function(.fun)) stop(".fun is not a function.") if (!inherits(.data, "split")) .data <- as.list(.data) res <- llply(.data = .data, .fun = .fun, ..., .progress = .progress, .inform = .inform, .parallel = .parallel, .paropts = .paropts) list_to_array(res, attr(.data, "split_labels"), .drop) } plyr/R/l_ply.r0000644000176000001440000000214112035653341012773 0ustar ripleyusers#' Split list, apply function, and discard results. #' #' For each element of a list, apply function and discard results #' #' @template ply #' @template l- #' @template -_ #' @export l_ply <- function(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE, .print = FALSE, .parallel = FALSE, .paropts = NULL) { if (is.character(.fun) || is.list(.fun)) .fun <- each(.fun) if (!is.function(.fun)) stop(".fun is not a function.") progress <- create_progress_bar(.progress) progress$init(length(.data)) on.exit(progress$term()) if (.parallel) { if (.print) message("Printing disabled for parallel processing") if (.progress != "none") message("Progress disabled for parallel processing") setup_parallel() .paropts$.combine <- function(...) NULL fe_call <- as.call(c(list(as.name("foreach"), d = as.name(".data")), .paropts)) fe <- eval(fe_call) fe %dopar% .fun(d, ...) } else { .data <- as.list(.data) for(i in seq_along(.data)) { x <- .fun(.data[[i]], ...) if (.print) print(x) progress$step() } } invisible() } plyr/R/join.r0000644000176000001440000001301412034572474012622 0ustar ripleyusers#' Join two data frames together. #' #' Join, like merge, is designed for the types of problems #' where you would use a sql join. #' #' The four join types return: #' #' \itemize{ #' \item \code{inner}: only rows with matching keys in both x and y #' \item \code{left}: all rows in x, adding matching columns from y #' \item \code{right}: all rows in y, adding matching columns from x #' \item \code{full}: all rows in x with matching columns in y, then the #' rows of y that don't match x. #' } #' #' Note that from plyr 1.5, \code{join} will (by default) return all matches, #' not just the first match, as it did previously. #' #' Unlike merge, preserves the order of x no matter what join type is used. #' If needed, rows from y will be added to the bottom. Join is often faster #' than merge, although it is somewhat less featureful - it currently offers #' no way to rename output or merge on different variables in the x and y #' data frames. #' #' @param x data frame #' @param y data frame #' @param by character vector of variable names to join by. If omitted, will #' match on all common variables. #' @param type type of join: left (default), right, inner or full. See #' details for more information. #' @param match how should duplicate ids be matched? Either match just the #' \code{"first"} matching row, or match \code{"all"} matching rows. Defaults #' to \code{"all"} for compatibility with merge, but \code{"first"} is #' significantly faster. #' @keywords manip #' @export #' @examples #' first <- ddply(baseball, "id", summarise, first = min(year)) #' system.time(b2 <- merge(baseball, first, by = "id", all.x = TRUE)) #' system.time(b3 <- join(baseball, first, by = "id")) #' #' b2 <- arrange(b2, id, year, stint) #' b3 <- arrange(b3, id, year, stint) #' stopifnot(all.equal(b2, b3)) join <- function(x, y, by = NULL, type = "left", match = "all") { type <- match.arg(type, c("left", "right", "inner", "full")) match <- match.arg(match, c("first", "all")) if (is.null(by)) { by <- intersect(names(x), names(y)) message("Joining by: ", paste(by, collapse = ", ")) } switch(match, "first" = .join_first(x, y, by, type), "all" = .join_all(x, y, by, type)) } .join_first <- function(x, y, by, type) { keys <- join.keys(x, y, by = by) x.cols <- setdiff(names(x), by) y.cols <- setdiff(names(y), by) if (type == "inner") { x.match <- match(keys$y, keys$x, 0) y.match <- match(keys$x, keys$y, 0) cbind( x[x.match, by, drop = FALSE], x[x.match, x.cols, drop = FALSE], y[y.match, y.cols, drop = FALSE] ) } else if (type == "left") { y.match <- match(keys$x, keys$y) y.matched <- unrowname(y[y.match, y.cols, drop = FALSE]) cbind(x[by], x[x.cols], y.matched) } else if (type == "right") { if (any(duplicated(keys$y))) { stop("Duplicated key in y", call. = FALSE) } new.cols <- setdiff(names(x), by) x.match <- match(keys$y, keys$x) x.matched <- unrowname(x[x.match, x.cols, drop = FALSE]) cbind(y[by], x.matched, y[y.cols]) } else if (type == "full") { # x with matching y's then any unmatched ys y.match <- match(keys$x, keys$y) y.matched <- unrowname(y[y.match, y.cols, drop = FALSE]) y.unmatch <- is.na(match(keys$y, keys$x)) rbind.fill(cbind(x[c(by, x.cols)], y.matched), y[y.unmatch, , drop = FALSE]) } } # Basic idea to perform a full cartesian product of the two data frames # and then evaluate which rows meet the merging criteria. But that is # horrendously inefficient, so we do various types of hashing, implemented # in R as split_indices .join_all <- function(x, y, by, type) { x.cols <- setdiff(names(x), by) y.cols <- setdiff(names(y), by) if (type == "inner") { ids <- join_ids(x, y, by) out <- cbind(x[ids$x, , drop = FALSE], y[ids$y, y.cols, drop = FALSE]) } else if (type == "left") { ids <- join_ids(x, y, by, all = TRUE) out <- cbind(x[ids$x, , drop = FALSE], y[ids$y, y.cols, drop = FALSE]) } else if (type == "right") { # Flip x and y, but make sure to put new columns in the right place new.cols <- setdiff(names(x), by) ids <- join_ids(y, x, by, all = TRUE) out <- cbind( y[ids$x, by, drop = FALSE], x[ids$y, x.cols, drop = FALSE], y[ids$x, y.cols, drop = FALSE] ) } else if (type == "full") { # x's with all matching y's, then non-matching y's - just the same as # join.first ids <- join_ids(x, y, by, all = TRUE) matched <- cbind(x[ids$x, , drop = FALSE], y[ids$y, y.cols, drop = FALSE]) unmatched <- y[setdiff(seq_len(nrow(y)), ids$y), , drop = FALSE] out <- rbind.fill(matched, unmatched) } unrowname(out) } join_ids <- function(x, y, by, all = FALSE) { keys <- join.keys(x, y, by = by) ys <- split_indices(keys$y, keys$n) length(ys) <- keys$n if (all) { # replace NULL with NA to preserve those x's without matching y's nulls <- vapply(ys, function(x) length(x) == 0, logical(1)) ys[nulls] <- list(NA_real_) } ys <- ys[keys$x] xs <- rep(seq_along(keys$x), vapply(ys, length, numeric(1))) list(x = xs, y = unlist(ys)) } #' Join keys. #' Given two data frames, create a unique key for each row. #' #' @param x data frame #' @param y data frame #' @param by character vector of variable names to join by #' @keywords internal #' @export join.keys <- function(x, y, by) { joint <- rbind.fill(x[by], y[by]) keys <- id(joint, drop = TRUE) n_x <- nrow(x) n_y <- nrow(y) list( x = keys[seq_len(n_x)], y = keys[n_x + seq_len(n_y)], n = attr(keys, "n") ) } plyr/R/join-all.r0000644000176000001440000000110112034572530013353 0ustar ripleyusers#' Recursively join a list of data frames. #' #' @param dfs A list of data frames. #' @inheritParams join #' @export #' @examples #' dfs <- list( #' a = data.frame(x = 1:10, a = runif(10)), #' b = data.frame(x = 1:10, b = runif(10)), #' c = data.frame(x = 1:10, c = runif(10)) #' ) #' join_all(dfs) #' join_all(dfs, "x") join_all <- function(dfs, by = NULL, type = "left", match = "all") { if (length(dfs) == 1) return(dfs[[1]]) joined <- dfs[[1]] for(i in 2:length(dfs)) { joined <- join(joined, dfs[[i]], by = by, type = type, match = match) } joined } plyr/R/indexed.r0000644000176000001440000000122012034020705013260 0ustar ripleyusers#' @S3method length indexed length.indexed <- function(x) length(x$index) #' @S3method names indexed names.indexed <- function(x) { labels <- attr(x, "split_labels") labels[] <- lapply(labels, as.character) do.call(paste, c(labels, list(sep = "."))) } #' @S3method as.list indexed as.list.indexed <- function(x, ...) { n <- length(x) out <- vector("list", n) for(i in seq_len(n)) { out[[i]] <- x[[i]] } names(out) <- names(x) class(out) <- c("split", "list") out } #' @S3method print indexed print.indexed <- function(x, ...) { print(as.list(x)) } #' @S3method [ indexed "[.indexed" <- function(x, ...) { as.list(x)[...] } plyr/R/indexed-data-frame.r0000644000176000001440000000227212037542535015304 0ustar ripleyusers#' An indexed data frame. #' #' Create a indexed list, a space efficient way of indexing into a large data frame #' #' @param env environment containing data frame #' @param index list of indices #' @param vars a character vector giving the variables used for subsetting #' @keywords internal indexed_df <- function(data, index, vars) { structure( list(data = data, index = index, vars = vars), class = c("indexed", "indexed_df") ) } #' @S3method [[ indexed_df "[[.indexed_df" <- function(x, i) { out <- extract_rows(x$data, x$index[[i]]) attr(out, "vars") <- x$vars out } extract_rows <- function(x, i) { if (!is.data.frame(x)) return(x[i, , drop = FALSE]) n <- ncol(x) out <- lapply(seq_len(n), extract_col_rows, df = x, i = i) names(out) <- names(x) class(out) <- "data.frame" attr(out, "row.names") <- c(NA_integer_, -length(out[[1]])) out } extract_col_rows <- function(df, i, j) { col <- .subset2(df, j) if (isS4(col)) return(col[i]) if (is.null(attr(col, "class"))) { .subset(col, i) } else if (inherits(col, "factor") || inherits(col, "POSIXt")) { out <- .subset(col, i) attributes(out) <- attributes(col) out } else { col[i] } } plyr/R/indexed-array.r0000644000176000001440000000270512034030772014412 0ustar ripleyusers#' An indexed array. #' #' Create a indexed array, a space efficient way of indexing into a large #' array. #' #' @param env environment containing data frame #' @param index list of indices #' @keywords internal #' @aliases indexed_array [[.indexed_array names.indexed_array #' length.indexed_array indexed_array <- function(env, index) { exact <- all(unlist(llply(index, is.numeric))) # Situations that should use [ # * data.frame # * normal array # * normal vector # * list-array with inexact indexing # # Situations that should use [[ # * list # * list-array with exact indexing if (is.list(env$data)) { if (is.data.frame(env$data) || (is.array(env$data) && !exact)) { subs <- "[" } else { subs <- "[[" } } else { subs <- "[" } # Don't drop if data is a data frame drop <- !is.data.frame(env$data) structure( list(env = env, index = index, drop = drop, subs = as.name(subs)), class = c("indexed_array", "indexed") ) } #' @S3method length indexed_array length.indexed_array <- function(x) nrow(x$index) #' @S3method [[ indexed_array "[[.indexed_array" <- function(x, i) { indices <- unname(x$index[i, , drop = TRUE]) indices <- lapply(indices, function(x) if (x == "") bquote() else x) call <- as.call(c( list(x$subs, quote(x$env$data)), indices, list(drop = x$drop))) eval(call) } #' @S3method names indexed names.indexed_array <- function(x) rownames(x$index) plyr/R/idataframe.r0000644000176000001440000000520712034020705013746 0ustar ripleyusers#' Construct an immutable data frame. #' #' An immutable data frame works like an ordinary data frame, except that when #' you subset it, it returns a reference to the original data frame, not a #' a copy. This makes subsetting substantially faster and has a big impact #' when you are working with large datasets with many groups. #' #' This method is still a little experimental, so please let me know if you #' run into any problems. #' #' @param df a data frame #' @return an immutable data frame #' @S3method [ idf #' @S3method names idf #' @S3method dim idf #' @S3method as.data.frame idf #' @S3method [[ idf #' @keywords manip #' @export #' @examples #' system.time(dlply(baseball, "id", nrow)) #' system.time(dlply(idata.frame(baseball), "id", nrow)) idata.frame <- function(df) { self <- new.env() self$`_data` <- df self$`_rows` <- seq_len(nrow(df)) self$`_cols` <- names(df) self$`_getters` <- lapply(names(df), function(name) { eval(substitute(function(v) { if (missing(v)) { `_data`[[name]][`_rows`] } else { stop("Immutable") } }, list(name = name)), envir=self) }) names(self$`_getters`) <- names(df) for (name in names(df)) { f <- self$`_getters`[[name]] environment(f) <- self makeActiveBinding(name, f, self) } structure(self, class = c("idf", "environment")) } "[.idf" <- function(x, i, j, drop = TRUE) { # Single column special cases if (nargs() == 2) { j <- i i <- TRUE drop <- FALSE } if (!missing(j) && length(j) == 1 && drop) { if (missing(i)) i <- TRUE return(x[[j]][i]) } # New rows rows <- x$`_rows` if (!missing(i)) { if (is.character(i)) stop("Row names not supported") rows <- rows[i] } # New cols cols <- x$`_cols` if (!missing(j)) { if (is.character(j)) { cols <- intersect(cols, j) } else { cols <- cols[j] } } # Make active bindings for functions like lm and eval that will treat this # object as an environment or list self <- new.env(parent = parent.env(x)) self$`_rows` <- rows self$`_cols` <- cols self$`_data` <- x$`_data` self$`_getters` <- x$`_getters` for (col in cols) { f <- self$`_getters`[[col]] environment(f) <- self makeActiveBinding(col, f, self) } structure(self, class = c("idf", "environment")) } names.idf <- function(x) x$`_cols` dim.idf <- function(x) c(length(x$`_rows`), length(x$`_cols`)) as.data.frame.idf <- function(x, ...) { x$`_data`[x$`_rows`, x$`_cols`] } "[[.idf" <- function(x, i) { if (is.numeric(i)) { i <- names(x)[i] } x$`_data`[[i]][x$`_rows`] } # "[[<-.idf" <- "[<-.idf" <- function(...) stop("Immutable") plyr/R/id.r0000644000176000001440000000411012057432447012254 0ustar ripleyusers#' Compute a unique numeric id for each unique row in a data frame. #' #' Properties: #' \itemize{ #' \item \code{order(id)} is equivalent to \code{do.call(order, df)} #' \item rows containing the same data have the same value #' \item if \code{drop = FALSE} then room for all possibilites #' } #' #' @param .variables list of variables #' @param drop drop unusued factor levels? #' @return a numeric vector with attribute n, giving total number of #' possibilities #' @keywords internal #' @seealso \code{\link{id_var}} #' @aliases id ninteraction #' @export id <- function(.variables, drop = FALSE) { # Drop all zero length inputs lengths <- vapply(.variables, length, integer(1)) .variables <- .variables[lengths != 0] if (length(.variables) == 0) { n <- nrow(.variables) %||% 0L return(structure(seq_len(n), n = n)) } # Special case for single variable if (length(.variables) == 1) { return(id_var(.variables[[1]], drop = drop)) } # Calculate individual ids ids <- rev(lapply(.variables, id_var, drop = drop)) p <- length(ids) # Calculate dimensions ndistinct <- vapply(ids, attr, "n", FUN.VALUE = numeric(1), USE.NAMES = FALSE) n <- prod(ndistinct) if (n > 2 ^ 31) { # Too big for integers, have to use strings, which will be much slower :( char_id <- do.call("paste", c(ids, sep = "\r")) res <- match(char_id, unique(char_id)) } else { combs <- c(1, cumprod(ndistinct[-p])) mat <- do.call("cbind", ids) res <- c((mat - 1L) %*% combs + 1L) } attr(res, "n") <- n if (drop) { id_var(res, drop = TRUE) } else { structure(as.integer(res), n = attr(res, "n")) } } ninteraction <- id #' Numeric id for a vector. #' @keywords internal id_var <- function(x, drop = FALSE) { if (length(x) == 0) return(structure(integer(), n = 0L)) if (!is.null(attr(x, "n")) && !drop) return(x) if (is.factor(x) && !drop) { id <- as.integer(addNA(x, ifany = TRUE)) n <- length(levels(x)) } else { levels <- sort(unique(x), na.last = TRUE) id <- match(x, levels) n <- max(id) } structure(id, n = n) } plyr/R/here.r0000644000176000001440000000165212035565262012611 0ustar ripleyusers#' Capture current evaluation context. #' #' This function captures the current context, making it easier #' to use \code{**ply} with functions that do special evaluation and #' need access to the environment where ddply was called from. #' #' @author Peter Meilstrup, \url{https://github.com/crowding} #' @param f a function that does non-standard evaluation #' @export #' @examples #' df <- data.frame(a = rep(c("a","b"), each = 10), b = 1:20) #' f1 <- function(label) { #' ddply(df, "a", mutate, label = paste(label, b)) #' } #' \dontrun{f1("name:")} #' # Doesn't work because mutate can't find label in the current scope #' #' f2 <- function(label) { #' ddply(df, "a", here(mutate), label = paste(label, b)) #' } #' f2("name:") #' # Works :) here <- function(f) { call <- substitute(function(...) (f)(...), list(f = f)) fun <- eval(call, parent.frame()) attr(fun, "srcref") <- srcfilecopy("", deparse(call)) fun } plyr/R/each.r0000644000176000001440000000420112034020705012542 0ustar ripleyusers#' Aggregate multiple functions into a single function. #' #' Combine multiple functions into a single function returning a named vector #' of outputs. #' Note: you cannot supply additional parameters for the summary functions #' #' @param ... functions to combine. each function should produce a single #' number as output #' @keywords manip #' @seealso \code{\link{summarise}} for applying summary functions to data #' @export #' @examples #' # Call min() and max() on the vector 1:10 #' each(min, max)(1:10) #' # This syntax looks a little different. It is shorthand for the #' # the following: #' f<- each(min, max) #' f(1:10) #' # Three equivalent ways to call min() and max() on the vector 1:10 #' each("min", "max")(1:10) #' each(c("min", "max"))(1:10) #' each(c(min, max))(1:10) #' # Call length(), min() and max() on a random normal vector #' each(length, mean, var)(rnorm(100)) each <- function(...) { fnames <- laply(match.call()[-1], deparse) fs <- list(...) if (length(fs[[1]]) > 1) { fs <- fs[[1]] # Jump through hoops to work out names snames <- as.list(match.call()[2])[[1]] fnames <- unlist(lapply(as.list(snames)[-1], deparse)) } # Find function names and replace with function objects char <- laply(fs, is.character) fnames[char] <- fs[char] fs[char] <- llply(fs[char], match.fun) unames <- names(fs) if (is.null(unames)) unames <- fnames unames[unames == ""] <- fnames[unames == ""] n <- length(fs) proto <- NULL result <- NULL if (n == 1) { # If there is only one function, things are simple. We just # need to name the output, if appropriate. function(x, ...) { res <- fs[[1]](x, ...) if (length(res) == 1) names(res) <- unames res } } else { function(x, ...) { # For n > 1 things are a little tricky # Construct protoype for output on first call if (is.null(proto)) { result <<- vector("list", length = n) names(result) <- unames for(i in 1:n) result[[i]] <- fs[[i]](x, ...) proto <<- list_to_vector(result) } else { for(i in 1:n) proto[[i]] <- fs[[i]](x, ...) } proto } } } plyr/R/dlply.r0000644000176000001440000000204612035653621013005 0ustar ripleyusers#' Split data frame, apply function, and return results in a list. #' #' For each subset of a data frame, apply function then combine results into a #' list. \code{dlply} is similar to \code{\link{by}} except that the results #' are returned in a different format. #' #' @template ply #' @template d- #' @template -l #' @export #' @examples #' linmod <- function(df) { #' lm(rbi ~ year, data = mutate(df, year = year - min(year))) #' } #' models <- dlply(baseball, .(id), linmod) #' models[[1]] #' #' coef <- ldply(models, coef) #' with(coef, plot(`(Intercept)`, year)) #' qual <- laply(models, function(mod) summary(mod)$r.squared) #' hist(qual) dlply <- function(.data, .variables, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL) { .variables <- as.quoted(.variables) pieces <- splitter_d(.data, .variables, drop = .drop) llply(.data = pieces, .fun = .fun, ..., .progress = .progress, .inform = .inform, .parallel = .parallel, .paropts = .paropts) } plyr/R/dimensions.r0000644000176000001440000000247112034611340014022 0ustar ripleyusers#' Number of dimensions. #' #' Number of dimensions of an array or vector #' #' @param x array #' @keywords internal dims <- function(x) length(amv_dim(x)) #' Dimensions. #' #' Consistent dimensions for vectors, matrices and arrays. #' #' @param x array, matrix or vector #' @keywords internal amv_dim <- function(x) if (is.vector(x)) length(x) else dim(x) #' Dimension names. #' #' Consistent dimnames for vectors, matrices and arrays. #' #' Unlike \code{\link{dimnames}} no part of the output will ever be #' null. If a component of dimnames is omitted, \code{amv_dimnames} #' will return an integer sequence of the appropriate length. #' #' @param x array, matrix or vector #' @keywords internal #' @export amv_dimnames <- function(x) { d <- if (is.vector(x)) list(names(x)) else dimnames(x) if (is.null(d)) d <- rep(list(NULL), dims(x)) null_names <- which(unlist(llply(d, is.null))) d[null_names] <- llply(null_names, function(i) seq_len(amv_dim(x)[i])) # if (is.null(names(d))) names(d) <- paste("X", 1:length(d), sep="") d } #' Reduce dimensions. #' #' Remove extraneous dimensions #' #' @param x array #' @keywords internal reduce_dim <- function(x) { subs <- lapply(dim(x), function(x) if (x == 1) 1 else bquote()) call <- as.call(c(list(as.name("["), quote(x)), subs, list(drop = TRUE))) eval(call) } plyr/R/defaults.r0000644000176000001440000000037612034020705013462 0ustar ripleyusers#' Set defaults. #' #' Convient method for combining a list of values with their defaults. #' #' @param x list of values #' @param y defaults #' @keywords manip #' @export defaults <- function(x, y) { c(x, y[setdiff(names(y), names(x))]) } plyr/R/ddply.r0000644000176000001440000000340112035657751013001 0ustar ripleyusers#' Split data frame, apply function, and return results in a data frame. #' #' For each subset of a data frame, apply function then combine results into a #' data frame. #' #' @template ply #' @template d- #' @template -d #' @seealso \code{\link{tapply}} for similar functionality in the base package #' @export #' @examples #' # Summarize a dataset by two variables #' require(plyr) #' dfx <- data.frame( #' group = c(rep('A', 8), rep('B', 15), rep('C', 6)), #' sex = sample(c("M", "F"), size = 29, replace = TRUE), #' age = runif(n = 29, min = 18, max = 54) #' ) #' #' # Note the use of the '.' function to allow #' # group and sex to be used without quoting #' ddply(dfx, .(group, sex), summarize, #' mean = round(mean(age), 2), #' sd = round(sd(age), 2)) #' #' # An example using a formula for .variables #' ddply(baseball[1:100,], ~ year, nrow) #' # Applying two functions; nrow and ncol #' ddply(baseball, .(lg), c("nrow", "ncol")) #' #' # Calculate mean runs batted in for each year #' rbi <- ddply(baseball, .(year), summarise, #' mean_rbi = mean(rbi, na.rm = TRUE)) #' # Plot a line chart of the result #' plot(mean_rbi ~ year, type = "l", data = rbi) #' #' # make new variable career_year based on the #' # start year for each player (id) #' base2 <- ddply(baseball, .(id), mutate, #' career_year = year - min(year) + 1 #' ) ddply <- function(.data, .variables, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL) { if (empty(.data)) return(.data) .variables <- as.quoted(.variables) pieces <- splitter_d(.data, .variables, drop = .drop) ldply(.data = pieces, .fun = .fun, ..., .progress = .progress, .inform = .inform, .parallel = .parallel, .paropts = .paropts) } plyr/R/data.r0000644000176000001440000000607212034020705012563 0ustar ripleyusers#' Monthly ozone measurements over Central America. #' #' #' This data set is a subset of the data from the 2006 ASA Data expo #' challenge, \url{http://stat-computing.org/dataexpo/2006/}. The data are #' monthly ozone averages on a very coarse 24 by 24 grid covering Central #' America, from Jan 1995 to Dec 2000. The data is stored in a 3d area with #' the first two dimensions representing latitude and longitude, and the third #' representing time. #' #' @docType data #' @name ozone #' @usage ozone #' @format A 24 x 24 x 72 numeric array #' @references \url{http://stat-computing.org/dataexpo/2006/} #' @keywords datasets #' @examples #' value <- ozone[1, 1, ] #' time <- 1:72 #' month.abbr <- c("Jan", "Feb", "Mar", "Apr", "May", #' "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec") #' month <- factor(rep(month.abbr, length = 72), levels = month.abbr) #' year <- rep(1:6, each = 12) #' deseasf <- function(value) lm(value ~ month - 1) #' #' models <- alply(ozone, 1:2, deseasf) #' coefs <- laply(models, coef) #' dimnames(coefs)[[3]] <- month.abbr #' names(dimnames(coefs))[3] <- "month" #' #' deseas <- laply(models, resid) #' dimnames(deseas)[[3]] <- 1:72 #' names(dimnames(deseas))[3] <- "time" #' #' dim(coefs) #' dim(deseas) NULL #' Yearly batting records for all major league baseball players #' #' This data frame contains batting statistics for a subset of players #' collected from \url{http://www.baseball-databank.org/}. There are a total #' of 21,699 records, covering 1,228 players from 1871 to 2007. Only players #' with more 15 seasons of play are included. #' #' @section Variables: #' Variables: #' \itemize{ #' \item id, unique player id #' \item year, year of data #' \item stint #' \item team, team played for #' \item lg, league #' \item g, number of games #' \item ab, number of times at bat #' \item r, number of runs #' \item h, hits, times reached base because of a batted, fair ball without #' error by the defense #' \item X2b, hits on which the batter reached second base safely #' \item X3b, hits on which the batter reached third base safely #' \item hr, number of home runs #' \item rbi, runs batted in #' \item sb, stolen bases #' \item cs, caught stealing #' \item bb, base on balls (walk) #' \item so, strike outs #' \item ibb, intentional base on balls #' \item hbp, hits by pitch #' \item sh, sacrifice hits #' \item sf, sacrifice flies #' \item gidp, ground into double play #' } #' @docType data #' @name baseball #' @usage baseball #' @format A 21699 x 22 data frame #' @references \url{http://www.baseball-databank.org/} #' @keywords datasets #' @examples #' baberuth <- subset(baseball, id == "ruthba01") #' baberuth$cyear <- baberuth$year - min(baberuth$year) + 1 #' #' calculate_cyear <- function(df) { #' mutate(df, #' cyear = year - min(year), #' cpercent = cyear / (max(year) - min(year)) #' ) #' } #' #' baseball <- ddply(baseball, .(id), calculate_cyear) #' baseball <- subset(baseball, ab >= 25) #' #' model <- function(df) { #' lm(rbi / ab ~ cyear, data=df) #' } #' model(baberuth) #' models <- dlply(baseball, .(id), model) NULL plyr/R/data-frame.r0000644000176000001440000000133212034020705013645 0ustar ripleyusers#' Make a function return a data frame. #' #' Create a new function that returns the existing function wrapped in a #' data.frame #' #' This is useful when calling \code{*dply} functions with a function that #' returns a vector, and you want the output in rows, rather than columns #' #' @keywords manip #' @param x function to make return a data frame #' @param row.names necessary to match the generic, but not used #' @param optional necessary to match the generic, but not used #' @param ... necessary to match the generic, but not used #' @method as.data.frame function #' @export as.data.frame.function <- function(x, row.names, optional, ...) { name <- deparse(substitute(x)) function(...) data.frame(value = x(...)) } plyr/R/daply.r0000644000176000001440000000356112035653600012772 0ustar ripleyusers#' Split data frame, apply function, and return results in an array. #' #' For each subset of data frame, apply function then combine results into #' an array. \code{daply} with a function that operates column-wise is #' similar to \code{\link{aggregate}}. #' #' @template ply #' @section Input: This function splits data frames by variables. #' @section Output: #' If there are no results, then this function will return a vector of #' length 0 (\code{vector()}). #' @param .data data frame to be processed #' @param .variables variables to split data frame by, as quoted #' variables, a formula or character vector #' @param .drop_i should combinations of variables that do not appear in the #' input data be preserved (FALSE) or dropped (TRUE, default) #' @return if results are atomic with same type and dimensionality, a #' vector, matrix or array; otherwise, a list-array (a list with #' dimensions) #' @param .drop_o should extra dimensions of length 1 in the output be #' dropped, simplifying the output. Defaults to \code{TRUE} #' @family array output #' @family data frame input #' @export #' @examples #' daply(baseball, .(year), nrow) #' #' # Several different ways of summarising by variables that should not be #' # included in the summary #' #' daply(baseball[, c(2, 6:9)], .(year), colwise(mean)) #' daply(baseball[, 6:9], .(baseball$year), colwise(mean)) #' daply(baseball, .(year), function(df) colwise(mean)(df[, 6:9])) daply <- function(.data, .variables, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop_i = TRUE, .drop_o = TRUE, .parallel = FALSE, .paropts = NULL) { .variables <- as.quoted(.variables) pieces <- splitter_d(.data, .variables, drop = .drop_i) laply(.data = pieces, .fun = .fun, ..., .progress = .progress, .inform = .inform, .drop = .drop_o, .parallel = .parallel, .paropts = .paropts) } plyr/R/d_ply.r0000644000176000001440000000120112047017444012760 0ustar ripleyusers#' Split data frame, apply function, and discard results. #' #' For each subset of a data frame, apply function and discard results #' #' @template ply #' @template d- #' @template -_ #' @export d_ply <- function(.data, .variables, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop = TRUE, .print = FALSE, .parallel = FALSE, .paropts = NULL) { .variables <- as.quoted(.variables) pieces <- splitter_d(.data, .variables, drop = .drop) l_ply(.data = pieces, .fun = .fun, ..., .progress = .progress, .inform = .inform, .print = .print, .parallel = .parallel, .paropts = .paropts) } plyr/R/count.r0000644000176000001440000000457212034020705013005 0ustar ripleyusers#' Count the number of occurences. #' #' Equivalent to \code{as.data.frame(table(x))}, but does not include #' combinations with zero counts. #' #' Speed-wise count is competitive with \code{\link{table}} for single #' variables, but it really comes into its own when summarising multiple #' dimensions because it only counts combinations that actually occur in the #' data. #' #' Compared to \code{\link{table}} + \code{\link{as.data.frame}}, \code{count} #' also preserves the type of the identifier variables, instead of converting #' them to characters/factors. #' #' @param df data frame to be processed #' @param vars variables to count unique values of #' @param wt_var optional variable to weight by - if this is non-NULL, count #' will sum up the value of this variable for each combination of id #' variables. #' @return a data frame with label and freq columns #' @keywords manip #' @seealso \code{\link{table}} for related functionality in the base package #' @export #' @examples #' # Count of each value of "id" in the first 100 cases #' count(baseball[1:100,], vars = "id") #' # Count of ids, weighted by their "g" loading #' count(baseball[1:100,], vars = "id", wt_var = "g") #' count(baseball, "id", "ab") #' count(baseball, "lg") #' # How many stints do players do? #' count(baseball, "stint") #' # Count of times each player appeared in each of the years they played #' count(baseball[1:100,], c("id", "year")) #' # Count of counts #' count(count(baseball[1:100,], c("id", "year")), "id", "freq") #' count(count(baseball, c("id", "year")), "freq") count <- function(df, vars = NULL, wt_var = NULL) { if (is.vector(df)) { df <- data.frame(x = df) } if (!is.null(vars)) { vars <- as.quoted(vars) df2 <- quickdf(eval.quoted(vars, df)) } else { df2 <- df } id <- ninteraction(df2, drop = TRUE) u_id <- !duplicated(id) labels <- df2[u_id, , drop = FALSE] labels <- labels[order(id[u_id]), , drop = FALSE] if (is.null(wt_var) && "freq" %in% names(df)) { message("Using freq as weighting variable") wt_var <- "freq" } if (!is.null(wt_var)) { wt_var <- as.quoted(wt_var) if (length(wt_var) > 1) { stop("wt_var must be a single variable", call. = FALSE) } wt <- eval.quoted(wt_var, df)[[1]] freq <- vaggregate(wt, id, sum, .default = 0) } else { freq <- tabulate(id, attr(id, "n")) } unrowname(data.frame(labels, freq)) } plyr/R/colwise.r0000644000176000001440000000506312034577436013340 0ustar ripleyusers#' Column-wise function. #' #' Turn a function that operates on a vector into a function that operates #' column-wise on a data.frame. #' #' \code{catcolwise} and \code{numcolwise} provide version that only operate #' on discrete and numeric variables respectively. #' #' @param .fun function #' @param .cols either a function that tests columns for inclusion, or a #' quoted object giving which columns to process #' @param ... other arguments passed on to \code{.fun} #' @export #' @examples #' # Count number of missing values #' nmissing <- function(x) sum(is.na(x)) #' #' # Apply to every column in a data frame #' colwise(nmissing)(baseball) #' # This syntax looks a little different. It is shorthand for the #' # the following: #' f <- colwise(nmissing) #' f(baseball) #' #' # This is particularly useful in conjunction with d*ply #' ddply(baseball, .(year), colwise(nmissing)) #' #' # To operate only on specified columns, supply them as the second #' # argument. Many different forms are accepted. #' ddply(baseball, .(year), colwise(nmissing, .(sb, cs, so))) #' ddply(baseball, .(year), colwise(nmissing, c("sb", "cs", "so"))) #' ddply(baseball, .(year), colwise(nmissing, ~ sb + cs + so)) #' #' # Alternatively, you can specify a boolean function that determines #' # whether or not a column should be included #' ddply(baseball, .(year), colwise(nmissing, is.character)) #' ddply(baseball, .(year), colwise(nmissing, is.numeric)) #' ddply(baseball, .(year), colwise(nmissing, is.discrete)) #' #' # These last two cases are particularly common, so some shortcuts are #' # provided: #' ddply(baseball, .(year), numcolwise(nmissing)) #' ddply(baseball, .(year), catcolwise(nmissing)) #' #' # You can supply additional arguments to either colwise, or the function #' # it generates: #' numcolwise(mean)(baseball, na.rm = TRUE) #' numcolwise(mean, na.rm = TRUE)(baseball) colwise <- function(.fun, .cols = true, ...) { if (!is.function(.cols)) { .cols <- as.quoted(.cols) filter <- function(df) eval.quoted(.cols, df) } else { filter <- function(df) Filter(.cols, df) } dots <- list(...) function(df, ...) { stopifnot(is.data.frame(df)) df <- strip_splits(df) filtered <- filter(df) if (length(filtered) == 0) return(data.frame()) out <- do.call("lapply", c(list(filtered, .fun, ...), dots)) names(out) <- names(filtered) quickdf(out) } } #' @rdname colwise #' @export catcolwise <- function(.fun, ...) { colwise(.fun, is.discrete, ...) } #' @rdname colwise #' @export numcolwise <- function(.fun, ...) { colwise(.fun, is.numeric, ...) } plyr/R/arrange.r0000644000176000001440000000316212035565262013303 0ustar ripleyusers#' Order a data frame by its colums. #' #' This function completes the subsetting, transforming and ordering triad #' with a function that works in a similar way to \code{\link{subset}} and #' \code{\link{transform}} but for reordering a data frame by its columns. #' This saves a lot of typing! #' #' @param df data frame to reorder #' @param ... expressions evaluated in the context of \code{df} and then fed #' to \code{\link{order}} #' @keywords manip #' @seealso \code{\link{order}} for sorting function in the base package #' @export #' @examples #' # sort mtcars data by cylinder and displacement #' mtcars[with(mtcars, order(cyl, disp)), ] #' # Same result using arrange: no need to use with(), as the context is implicit #' # NOTE: plyr functions do NOT preserve row.names #' arrange(mtcars, cyl, disp) #' # Let's keep the row.names in this example #' myCars = cbind(vehicle=row.names(mtcars), mtcars) #' arrange(myCars, cyl, disp) #' # Sort with displacement in descending order #' arrange(myCars, cyl, desc(disp)) arrange <- function(df, ...) { stopifnot(is.data.frame(df)) ord <- eval(substitute(order(...)), df, parent.frame()) if(length(ord) != nrow(df)) { stop("Length of ordering vectors don't match data frame size", call. = FALSE) } unrowname(df[ord, , drop = FALSE]) } #' Descending order. #' #' Transform a vector into a format that will be sorted in descending order. #' #' @param x vector to transform #' @keywords manip #' @export #' @examples #' desc(1:10) #' desc(factor(letters)) #' first_day <- seq(as.Date("1910/1/1"), as.Date("1920/1/1"), "years") #' desc(first_day) desc <- function(x) -xtfrm(x) plyr/R/alply.r0000644000176000001440000000304512055477222013005 0ustar ripleyusers#' Split array, apply function, and return results in a list. #' #' For each slice of an array, apply function then combine results into a #' list. #' #' The list will have "dims" and "dimnames" corresponding to the #' margins given. For instance \code{alply(x, c(3,2), ...)} where #' \code{x} has dims \code{c(4,3,2)} will give a result with dims #' \code{c(2,3)}. #' #' \code{alply} is somewhat similar to \code{\link{apply}} for cases #' where the results are not atomic. #' #' @template ply #' @template a- #' @template -l #' @param .dims if \code{TRUE}, copy over dimensions and names from input. #' @export #' @examples #' alply(ozone, 3, quantile) #' alply(ozone, 3, function(x) table(round(x))) alply <- function(.data, .margins, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL, .dims = FALSE) { pieces <- splitter_a(.data, .margins, .expand) res <- llply(.data = pieces, .fun = .fun, ..., .progress = .progress, .inform = .inform, .parallel = .parallel, .paropts = .paropts) if (.dims) { labels <- attr(pieces, "split_labels") #splitting a dataframe along dimension 1 is a special case which #gets a different output from splitter_a, so guard against that if (length(labels) == length(.margins)) { res_labels <- lapply(labels, function(x) as.character(unique(x))) res_dim <- sapply(res_labels, length) if (length(res_dim) > 0) { dim(res) <- res_dim dimnames(res) <- res_labels } } } res } plyr/R/adply.r0000644000176000001440000000111712035653775013002 0ustar ripleyusers#' Split array, apply function, and return results in a data frame. #' #' For each slice of an array, apply function then combine results into a data #' frame. #' #' @template ply #' @template a- #' @template -d #' @export adply <- function(.data, .margins, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL) { pieces <- splitter_a(.data, .margins, .expand) ldply(.data = pieces, .fun = .fun, ..., .progress = .progress, .inform = .inform, .parallel = .parallel, .paropts = .paropts) } plyr/R/aaply.r0000644000176000001440000000265412037542535012777 0ustar ripleyusers#' Split array, apply function, and return results in an array. #' #' For each slice of an array, apply function, keeping results as an array. #' #' This function is very similar to \code{\link{apply}}, except that it will #' always return an array, and when the function returns >1 d data structures, #' those dimensions are added on to the highest dimensions, rather than the #' lowest dimensions. This makes \code{aaply} idempotent, so that #' \code{aaply(input, X, identity)} is equivalent to \code{aperm(input, X)}. #' #' @template ply #' @template a- #' @template -a #' @export #' @examples #' dim(ozone) #' aaply(ozone, 1, mean) #' aaply(ozone, 1, mean, .drop = FALSE) #' aaply(ozone, 3, mean) #' aaply(ozone, c(1,2), mean) #' #' dim(aaply(ozone, c(1,2), mean)) #' dim(aaply(ozone, c(1,2), mean, .drop = FALSE)) #' #' aaply(ozone, 1, each(min, max)) #' aaply(ozone, 3, each(min, max)) #' #' standardise <- function(x) (x - min(x)) / (max(x) - min(x)) #' aaply(ozone, 3, standardise) #' aaply(ozone, 1:2, standardise) #' #' aaply(ozone, 1:2, diff) aaply <- function(.data, .margins, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL) { pieces <- splitter_a(.data, .margins, .expand) laply(.data = pieces, .fun = .fun, ..., .progress = .progress, .inform = .inform, .drop = .drop, .parallel = .parallel, .paropts = .paropts) } plyr/R/a_ply.r0000644000176000001440000000106712035653144012767 0ustar ripleyusers#' Split array, apply function, and discard results. #' #' For each slice of an array, apply function and discard results #' #' @template ply #' @template a- #' @template -_ #' @export a_ply <- function(.data, .margins, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .print = FALSE, .parallel = FALSE, .paropts = NULL) { pieces <- splitter_a(.data, .margins, .expand) l_ply(.data = pieces, .fun = .fun, ..., .progress = .progress, .print = .print, .parallel = .parallel, .paropts = .paropts) } plyr/NEWS0000644000176000001440000004166712055563707012017 0ustar ripleyusersVersion 1.8 ------------------------------------------------------------------------------ NEW FEATURES AND FUNCTIONS * `**ply` gain a `.inform` argument (previously only available in `llply`) - this gives more useful debugging information at the cost of some speed. (Thanks to Brian Diggs, #57) * if `.dims = TRUE` `alply`'s output gains dimensions and dimnames, similar to `apply`. Sequential indexing of a list produced by `alply` should be unaffected. (Peter Meilstrup) * `colwise`, `numcolwise` and `catcolwise` now all accept additional arguments in .... (Thanks to Stavros Macrakis, #62) * `here` makes it possible to use `**ply` + a function that uses non-standard evaluation (e.g. `summarise`, `mutate`, `subset`, `arrange`) inside a function. (Thanks to Peter Meilstrup, #3) * `join_all` recursively joins a list of data frames. (Fixes #29) * `name_rows` provides a convenient way of saving and then restoring row names so that you can preserve them if you need to. (#61) * `progress_time` (used with `.progress = "time"`) estimates the amount of time remaining before the job is completed. (Thanks to Mike Lawrence, #78) * `summarise` now works iteratively so that later columns can refer to earlier. (Thanks to Jim Hester, #44) * `take` makes it easy to subset along an arbitrary dimension. * Improved documentation thanks to patches from Tim Bates. PARALLEL PLYR * `**ply` gains a `.paropts` argument, a list of options that is passed onto `foreach` for controlling parallel computation. * `*_ply` now accepts `.parallel` argument to enable parallel processing. (Fixes #60) * Progress bars are disabled when using parallel plyr (Fixes #32) PERFORMANCE IMPROVEMENTS * `a*ply`: 25x speedup when indexing array objects, 3x speedup when indexing data frames. This should substantially reduce the overhead of using `a*ply` * `d*ply` subsetting has been considerably optimised: this will have a small impact unless you have a very large number of groups, in which case it will be considerably faster. * `idata.frame`: Subsetting immutable data frames with `[.idf` is now faster (Peter Meilstrup) * `quickdf` is around 20% faster * `split_indices`, which powers much internal splitting code (like `vaggregate`, `join` and `d*ply`) is about 2x faster. It was already incredible fast ~0.2s for 1,000,000 obs, so this won't have much impact on overall performance BUG FIXES * `*aply` functions now bind list mode results into a list-array (Peter Meilstrup) * `*aply` now accepts 0-dimension arrays as inputs. (#88) * `*dply` now deals better with matrix results, converting them to data frames, rather than vectors. (Fixes #12) * `d*ply` will now preserve factor levels input if `drop = FALSE` (#81) * `join` works correctly when there are no common rows (Fixes #74), or when one input has no rows (Fixes #48). It also consistently orders the columns: common columns, then x cols, then y cols (Fixes #40). * `quickdf` correctly handles NA variable names. (Fixes #66. Thanks to Scott Kostyshak) * `rbind.fill` and `rbind.fill.matrix` work consistently with matrices and data frames with zero rows. Fixes #79. (Peter Meilstrup) * `rbind.fill` now stops if inputs are not data frames. (Fixes #51) * `rbind.fill` now works consistently with 0 column data frames * `round_any` now works with `POSIXct` objects, thanks to Jean-Olivier Irisson (#76) Version 1.7.1 ------------------------------------------------------------------------------ * Fix bug in id, using numeric instead of integer Version 1.7 ------------------------------------------------------------------------------ * `rbind.fill`: if a column contains both factors and characters (in different inputs), the resulting column will be coerced to character * When there are more than 2^31 distinct combinations `id`, switches to a slower fallback strategy using strings (inspired by `merge`) that guarantees correct results. This fixes problems with `join` when joining across many columns. (Fixes #63) * `split_indices` checks input more aggressively to prevent segfaults. Fixes #43. * fix small bug in `loop_apply` which lead to segfaults in certain circumstances. (Thanks to Pål Westermark for patch) * `itertools` and `iterators` moved to suggests from imports so that plyr now only depends on base R. Version 1.6 ------------------------------------------------------------------------------ * documentation improved using new features of `roxygen2` * fixed namespacing issue which lead to lost labels when subsetting the results of `*lply` * `colwise` automatically strips off split variables. * `rlply` now correctly deals with `rlply(4, NULL)` (thanks to bug report from Eric Goldlust) * `rbind.fill` tries harder to keep attributes, retaining the attributes from the first occurrence of each column it finds. It also now works with variables of class `POSIXlt` and preserves the ordered status of factors. * `arrange` now works with one column data frames Version 1.5.2 ------------------------------------------------------------------------------ * `d*ply` returns correct number of rows when function returns vector * fix NAMESPACE bug which was causing problems with ggplot2 Version 1.5.1 ------------------------------------------------------------------------------ * `rbind.fill` now treats 1d arrays in the same way as `rbind` (i.e. it turns them into ordinary vectors) * fix bug in rename when renaming multiple columns Version 1.5 (2011-03-02) ------------------------------------------------------------------------------ NEW FEATURES * new `strip_splits` function removes splitting variables from the data frames returned by `ddply`. * `rename` moved in from reshape, and rewritten. * new `match_df` function makes it easy to subset a data frame to only contain values matching another data frame. Inspired by http://stackoverflow.com/questions/4693849. BUG FIXES * `**ply` now works when passed a list of functions * `*dply` now correctly names output even when some output combinations are missing (NULL) (Thanks to bug report from Karl Ove Hufthammer) * `*dply` preserves the class of many more object types. * `a*ply` now correctly works with zero length margins, operating on the entire object (Thanks to bug report from Stavros Macrakis) * `join` now implements joins in a more SQL like way, returning all possible matches, not just the first one. It is still a (little) faster than merge. The previous behaviour is accessible with `match = "first"`. * `join` is now more symmetric so that `join(x, y, "left")` is closer to `join(y, x, "right")`, modulo column ordering * `named.quoted` failed when quoted expressions were longer than 50 characters. (Thanks to bug report from Eric Goldlust) * `rbind.fill` now correctly maintains POSIXct tzone attributes and preserves missing factor levels * `split_labels` correctly preserves empty factor levels, which means that `drop = FALSE` should work in more places. Use `base::droplevels` to remove levels that don't occur in the data, and `drop = T` to remove combinations of levels that don't occur. * `vaggregate` now passes `...` to the aggregation function when working out the output type (thanks to bug report by Pavan Racherla) Version 1.4.1 (2011-04-05) ------------------------------------------------------------------------------ * Add citation to JSS article Version 1.4 (2011-01-03) ------------------------------------------------------------------------------ * `count` now takes an additional parameter `wt_var` which allows you to compute weighted sums. This is as fast, or faster than, `tapply` or `xtabs`. * Really fix bug in `names.quoted` * `.` now captures the environment in which it was evaluated. This should fix an esoteric class of bugs which no-one probably ever encountered, but will form the basis for an improved version of `ggplot2::aes`. Version 1.3.1 (2010-12-30) ------------------------------------------------------------------------------ * Fix bug in `names.quoted` that interfered with ggplot2 Version 1.3 (2010-12-28) ------------------------------------------------------------------------------ NEW FEATURES * new function `mutate` that works like transform to add new columns or overwrite existing columns, but computes new columns iteratively so later transformations can use columns created by earlier transformations. (It's also about 10x faster) (Fixes #21) BUG FIXES * split column names are no longer coerced to valid R names. * `quickdf` now adds names if missing * `summarise` preserves variable names if explicit names not provided (Fixes #17) * `arrays` with names should be sorted correctly once again (also fixed a bug in the test case that prevented me from catching this automatically) * `m_ply` no longer possesses .parallel argument (mistakenly added) * `ldply` (and hence `adply` and `ddply`) now correctly passes on .parallel argument (Fixes #16) * `id` uses a better strategy for converting to integers, making it possible to use for cases with larger potential numbers of combinations Version 1.2.1 (2010-09-10) ------------------------------------------------------------------------------ * Fix bug in llply fast path that causes problems with ggplot2. Version 1.2 (2010-09-09) ------------------------------------------------------------------------------ NEW FEATURES * l*ply, d*ply, a*ply and m*ply all gain a .parallel argument that when TRUE, applies functions in parallel using a parallel backend registered with the foreach package: x <- seq_len(20) wait <- function(i) Sys.sleep(0.1) system.time(llply(x, wait)) # user system elapsed # 0.007 0.005 2.005 library(doMC) registerDoMC(2) system.time(llply(x, wait, .parallel = TRUE)) # user system elapsed # 0.020 0.011 1.038 This work has been generously supported by BD (Becton Dickinson). MINOR CHANGES * a*ply and m*ply gain an .expand argument that controls whether data frames produce a single output dimension (one element for each row), or an output dimension for each variable. * new vaggregate (vector aggregate) function, which is equivalent to tapply, but much faster (~ 10x), since it avoids copying the data. * llply: for simple lists and vectors, with no progress bar, no extra info, and no parallelisation, llply calls lapply directly to avoid all the overhead associated with those unused extra features. * llply: in serial case, for loop replaced with custom C function that takes about 40% less time (or about 20% less time than lapply). Note that as a whole, llply still has much more overhead than lapply. * round_any now lives in plyr instead of reshape BUG FIXES * list_to_array works correct even when there are missing values in the array. This is particularly important for daply. Version 1.1 (2010-07-19) ------------------------------------------------------------------------------ * *dply deals more gracefully with the case when all results are NULL (fixes #10) * *aply correctly orders output regardless of dimension names (fixes #11) * join gains type = "full" which preserves all x and y rows Version 1.0 (2010-07-02) ------------------------------------------------------------------------------ New functions: * arrange, a new helper method for reordering a data frame. * count, a version of table that returns data frames immediately and that is much much faster for high-dimensional data. * desc makes it easy to sort any vector in descending order * join, works like merge but can be much faster and has a somewhat simpler syntax drawing from SQL terminology * rbind.fill.matrix is like rbind.fill but works for matrices, code contributed by C. Beleites Speed improvements * experimental immutable data frame (idata.frame) that vastly speeds up subsetting - for large datasets with large numbers of groups, this can yield 10-fold speed ups. See examples in ?idata.frame to see how to use it. * rbind.fill rewritten again to increase speed and work with more data types * d*ply now much faster with nested groups This work has been generously supported by BD (Becton Dickinson). New features: * d*ply now accepts NULL for splitting variables, indicating that the data should not be split * plyr no longer exports internal functions, many of which were causing clashes with other packages * rbind.fill now works with data frame columns that are lists or matrices * test suite ensures that plyr behaviour is correct and will remain correct as I make future improvements. Bug fixes: * **ply: if zero splits, empty list(), data.frame() or logical() returned, as appropriate for the output type * **ply: leaving .fun as NULL now always returns list (thanks to Stavros Macrakis for the bug report) * a*ply: labels now respect options(stringAsFactors) * each: scoping bug fixed, thanks to Yasuhisa Yoshida for the bug report * list_to_dataframe is more consistent when processing a single data frame * NAs preserved in more places * progress bars: guaranteed to terminate even if **ply prematurely terminates * progress bars: misspelling gives informative warning, instead of uninformative error * splitter_d: fixed ordering bug when .drop = FALSE Version 0.1.9 (2009-06-23) ------------------------------------------------------------------------------ * fix bug in rbind.fill when NULLs present in list * improve each to recognise when all elements are numeric * fix labelling bug in d*ply when .drop = FALSE * additional methods for quoted objects * add summarise helper - this function is like transform, but creates a new data frame rather than reusing the old (thanks to Brendan O'Connor for the neat idea) Version 0.1.8 (2009-04-20) ------------------------------------------------------------------------------ * made rbind a little faster (~20%) using an idea from Richard Raubertas * daply now works correctly when splitting variables that contain empty factor levels Version 0.1.7 (2009-04-15) ------------------------------------------------------------------------------ * Version that rbind.fill copies attributes. Version 0.1.6 (2009-04-15) ------------------------------------------------------------------------------ Improvements: * all ply functions deal more elegantly when given function names: can supply a vector of function names, and name is used as label in output * failwith and each now work with function names as well as functions (i.e. "nrow" instead of nrow) * each now accepts a list of functions or a vector of function names * l*ply will use list names where present * if .inform is TRUE, error messages will give you information about where errors within your data - hopefully this will make problems easier to track down * d*ply no longer converts splitting variables to factors when drop = T (thanks to bug report from Charlotte Wickham) Speed-ups * massive speed ups for splitting large arrays * fixed typo that was causing a 50% speed penalty for d*ply * rewritten rbind.fill is considerably (> 4x) faster for many data frames * colwise about twice as fast Bug fixes: * daply: now works when the data frame is split by multiple variables * aaply: now works with vectors * ddply: first variable now varies slowest as you'd expect Version 0.1.5 (2009-02-23) ------------------------------------------------------------------------------ * colwise now accepts a quoted list as its second argument. This allows you to specify the names of columns to work on: colwise(mean, .(lat, long)) * d_ply and a_ply now correctly pass ... to the function Version 0.1.4 (2008-12-12) ------------------------------------------------------------------------------ * Greatly improved speed (> 10x faster) and memory usage (50%) for splitting data frames with many combinations * Splitting variables containing missing values now handled consistently Version 0.1.3 (2008-11-19) ------------------------------------------------------------------------------ * Fixed problem where when splitting by a variable that contained missing values, missing combinations would be drop, and labels wouldn't match up Version 0.1.2 (2008-11-18) ------------------------------------------------------------------------------ * a*ply now works correctly with array-lists * drop. -> .drop * r*ply now works with ... * use inherits instead of is so method package doesn't need to be loaded * fix bug with using formulas Version 0.1.1 (2008-10-08) ------------------------------------------------------------------------------ * argument names now start with . (instead of ending with it) - this should prevent name clashes with arguments of the called function * return informative error if .fun is not a function * use full names in all internal calls to avoid argument name clashesplyr/NAMESPACE0000644000176000001440000000377212043514645012524 0ustar ripleyusersS3method("[",idf) S3method("[",indexed) S3method("[",quoted) S3method("[",split) S3method("[[",idf) S3method("[[",indexed_array) S3method("[[",indexed_df) S3method(as.data.frame,"function") S3method(as.data.frame,idf) S3method(as.list,indexed) S3method(as.list,split) S3method(as.quoted,"NULL") S3method(as.quoted,call) S3method(as.quoted,character) S3method(as.quoted,factor) S3method(as.quoted,formula) S3method(as.quoted,name) S3method(as.quoted,numeric) S3method(as.quoted,quoted) S3method(c,quoted) S3method(dim,idf) S3method(length,indexed) S3method(length,indexed_array) S3method(names,idf) S3method(names,indexed) S3method(names,quoted) S3method(print,indexed) S3method(print,quoted) S3method(print,split) S3method(round_any,POSIXct) S3method(round_any,numeric) export(.) export(a_ply) export(aaply) export(adply) export(alply) export(amv_dimnames) export(arrange) export(as.quoted) export(catcolwise) export(colwise) export(compact) export(count) export(create_progress_bar) export(d_ply) export(daply) export(ddply) export(defaults) export(desc) export(dlply) export(each) export(empty) export(eval.quoted) export(failwith) export(here) export(id) export(idata.frame) export(is.discrete) export(is.formula) export(is.quoted) export(isplit2) export(join) export(join.keys) export(join_all) export(l_ply) export(laply) export(ldply) export(liply) export(llply) export(m_ply) export(maply) export(mapvalues) export(match_df) export(mdply) export(mlply) export(mutate) export(name_rows) export(numcolwise) export(progress_none) export(progress_text) export(progress_time) export(progress_tk) export(progress_win) export(quickdf) export(r_ply) export(raply) export(rbind.fill) export(rbind.fill.matrix) export(rdply) export(rename) export(revalue) export(rlply) export(round_any) export(splat) export(split_indices) export(split_labels) export(strip_splits) export(summarise) export(summarize) export(take) export(true) export(try_default) export(tryapply) export(unrowname) export(vaggregate) importFrom(stats,setNames) useDynLib(plyr) plyr/man/0000755000176000001440000000000012057740033012044 5ustar ripleyusersplyr/man/vaggregate.Rd0000644000176000001440000000311612057740032014447 0ustar ripleyusers\name{vaggregate} \alias{vaggregate} \title{Vector aggregate.} \usage{ vaggregate(.value, .group, .fun, ..., .default = NULL, .n = nlevels(.group)) } \arguments{ \item{.value}{vector of values to aggregate} \item{.group}{grouping vector} \item{.fun}{aggregation function} \item{...}{other arguments passed on to \code{.fun}} \item{.default}{default value used for missing groups. This argument is also used as the template for function output.} \item{.n}{total number of groups} } \description{ This function is somewhat similar to \code{tapply}, but is designed for use in conjunction with \code{id}. It is simpler in that it only accepts a single grouping vector (use \code{\link{id}} if you have more) and uses \code{\link{vapply}} internally, using the \code{.default} value as the template. } \details{ \code{vaggregate} should be faster than \code{tapply} in most situations because it avoids making a copy of the data. } \examples{ # Some examples of use borrowed from ?tapply n <- 17; fac <- factor(rep(1:3, length = n), levels = 1:5) table(fac) vaggregate(1:n, fac, sum) vaggregate(1:n, fac, sum, .default = NA_integer_) vaggregate(1:n, fac, range) vaggregate(1:n, fac, range, .default = c(NA, NA) + 0) vaggregate(1:n, fac, quantile) # Unlike tapply, vaggregate does not support multi-d output: tapply(warpbreaks$breaks, warpbreaks[,-1], sum) vaggregate(warpbreaks$breaks, id(warpbreaks[,-1]), sum) # But it is about 10x faster x <- rnorm(1e6) y1 <- sample.int(10, 1e6, replace = TRUE) system.time(tapply(x, y1, mean)) system.time(vaggregate(x, y1, mean)) } plyr/man/unrowname.Rd0000644000176000001440000000027112057740032014345 0ustar ripleyusers\name{unrowname} \alias{unrowname} \title{Un-rowname.} \usage{ unrowname(x) } \arguments{ \item{x}{data frame} } \description{ Strip rownames from an object } \keyword{internal} plyr/man/tryapply.Rd0000644000176000001440000000035012057740032014214 0ustar ripleyusers\name{tryapply} \alias{tryapply} \title{Apply with built in try. Uses compact, lapply and tryNULL} \usage{ tryapply(list, fun, ...) } \description{ Apply with built in try. Uses compact, lapply and tryNULL } \keyword{internal} plyr/man/try_default.Rd0000644000176000001440000000110312057740032014647 0ustar ripleyusers\name{try_default} \alias{tryNULL} \alias{try_default} \title{Try, with default in case of error.} \usage{ try_default(expr, default, quiet = FALSE) } \arguments{ \item{expr}{expression to try} \item{default}{default value in case of error} \item{quiet}{should errors be printed (TRUE) or ignored (FALSE, default)} } \description{ \code{try_default} wraps try so that it returns a default value in the case of error. } \details{ \code{tryNULL} provides a useful special case when dealing with lists. } \seealso{ \code{\link{tryapply}} } \keyword{internal} plyr/man/true.Rd0000644000176000001440000000043312057740032013311 0ustar ripleyusers\name{true} \alias{true} \title{Function that always returns true.} \usage{ true(...) } \arguments{ \item{...}{all input ignored} } \value{ \code{TRUE} } \description{ Function that always returns true. } \seealso{ \code{\link{colwise}} which uses it } \keyword{internal} plyr/man/take.Rd0000644000176000001440000000120512057740032013254 0ustar ripleyusers\name{take} \alias{take} \title{Take a subset along an arbitrary dimension} \usage{ take(x, along, indices, drop = FALSE) } \arguments{ \item{x}{matrix or array to subset} \item{along}{dimension to subset along} \item{indices}{the indices to select} \item{drop}{should the dimensions of the array be simplified? Defaults to \code{FALSE} which is the opposite of the useful R default.} } \description{ Take a subset along an arbitrary dimension } \examples{ x <- array(seq_len(3 * 4 * 5), c(3, 4, 5)) take(x, 3, 1) take(x, 2, 1) take(x, 1, 1) take(x, 3, 1, drop = TRUE) take(x, 2, 1, drop = TRUE) take(x, 1, 1, drop = TRUE) } plyr/man/summarise.Rd0000644000176000001440000000157412057740032014346 0ustar ripleyusers\name{summarise} \alias{summarise} \alias{summarize} \title{Summarise a data frame.} \usage{ summarise(.data, ...) } \arguments{ \item{.data}{the data frame to be summarised} \item{...}{further arguments of the form var = value} } \description{ Summarise works in an analagous way to transform, except instead of adding columns to an existing data frame, it creates a new data frame. This is particularly useful in conjunction with \code{\link{ddply}} as it makes it easy to perform group-wise summaries. } \examples{ # Let's extract the number of teams and total period of time # covered by the baseball dataframe summarise(baseball, duration = max(year) - min(year), nteams = length(unique(team))) # Combine with ddply to do that for each separate id ddply(baseball, "id", summarise, duration = max(year) - min(year), nteams = length(unique(team))) } \keyword{manip} plyr/man/strip_splits.Rd0000644000176000001440000000104212057740032015066 0ustar ripleyusers\name{strip_splits} \alias{strip_splits} \title{Remove splitting variables from a data frame.} \usage{ strip_splits(df) } \arguments{ \item{df}{data frame produced by \code{d*ply}.} } \description{ This is useful when you want to perform some operation to every column in the data frame, except the variables that you have used to split it. These variables will be automatically added back on to the result when combining all results together. } \examples{ dlply(mtcars, c("vs", "am")) dlply(mtcars, c("vs", "am"), strip_splits) } plyr/man/splitter_d.Rd0000644000176000001440000000302012057740032014476 0ustar ripleyusers\name{splitter_d} \alias{splitter_d} \title{Split a data frame by variables.} \usage{ splitter_d(data, .variables = NULL, drop = TRUE) } \arguments{ \item{data}{data frame} \item{.variables}{a \link{quoted} list of variables} \item{drop}{drop unnused factor levels?} } \value{ a list of data.frames, with attributes that record split details } \description{ Split a data frame into pieces based on variable contained in that data frame } \details{ This is the workhorse of the \code{d*ply} functions. Based on the variables you supply, it breaks up a single data frame into a list of data frames, each containing a single combination from the levels of the specified variables. This is basically a thin wrapper around \code{\link{split}} which evaluates the variables in the context of the data, and includes enough information to reconstruct the labelling of the data frame after other operations. } \examples{ plyr:::splitter_d(mtcars, .(cyl)) plyr:::splitter_d(mtcars, .(vs, am)) plyr:::splitter_d(mtcars, .(am, vs)) mtcars$cyl2 <- factor(mtcars$cyl, levels = c(2, 4, 6, 8, 10)) plyr:::splitter_d(mtcars, .(cyl2), drop = TRUE) plyr:::splitter_d(mtcars, .(cyl2), drop = FALSE) mtcars$cyl3 <- ifelse(mtcars$vs == 1, NA, mtcars$cyl) plyr:::splitter_d(mtcars, .(cyl3)) plyr:::splitter_d(mtcars, .(cyl3, vs)) plyr:::splitter_d(mtcars, .(cyl3, vs), drop = FALSE) } \seealso{ \code{\link{.}} for quoting variables, \code{\link{split}} Other splitter functions: \code{\link{splitter_a}} } \keyword{internal} plyr/man/splitter_a.Rd0000644000176000001440000000264112057740032014503 0ustar ripleyusers\name{splitter_a} \alias{splitter_a} \title{Split an array by .margins.} \usage{ splitter_a(data, .margins = 1L, .expand = TRUE) } \arguments{ \item{data}{>1d data structure (matrix, data.frame or array)} \item{.margins}{a vector giving the subscripts to split up \code{data} by.} \item{.expand}{if splitting a dataframe by row, should output be 1d (expand = FALSE), with an element for each row; or nd (expand = TRUE), with a dimension for each variable.} } \value{ a list of lower-d slices, with attributes that record split details } \description{ Split a 2d or higher data structure into lower-d pieces based } \details{ This is the workhorse of the \code{a*ply} functions. Given a >1 d data structure (matrix, array, data.frame), it splits it into pieces based on the subscripts that you supply. Each piece is a lower dimensional slice. The margins are specified in the same way as \code{\link{apply}}, but \code{splitter_a} just splits up the data, while \code{apply} also applies a function and combines the pieces back together. This function also includes enough information to recreate the split from attributes on the list of pieces. } \examples{ plyr:::splitter_a(mtcars, 1) plyr:::splitter_a(mtcars, 2) plyr:::splitter_a(ozone, 2) plyr:::splitter_a(ozone, 3) plyr:::splitter_a(ozone, 1:2) } \seealso{ Other splitter functions: \code{\link{splitter_d}} } \keyword{internal} plyr/man/split_labels.Rd0000644000176000001440000000064212057740033015012 0ustar ripleyusers\name{split_labels} \alias{split_labels} \title{Generate labels for split data frame.} \usage{ split_labels(splits, drop, id = plyr::id(splits, drop = TRUE)) } \arguments{ \item{list}{of variables to split up by} \item{whether}{all possible combinations should be considered, or only those present in the data} } \description{ Create data frame giving labels for split data frame. } \keyword{internal} plyr/man/split_indices.Rd0000644000176000001440000000065712057740032015173 0ustar ripleyusers\name{split_indices} \alias{split_indices} \title{Split indices.} \usage{ split_indices(group, n = max(group)) } \arguments{ \item{index}{integer indices} \item{group}{integer groups} \item{n}{largest integer (may not appear in index)} } \description{ An optimised version of split for the special case of splitting row indices into groups, as used by \code{\link{splitter_d}} } \keyword{internal} \keyword{manip} plyr/man/splat.Rd0000644000176000001440000000125512057740032013460 0ustar ripleyusers\name{splat} \alias{splat} \title{`Splat' arguments to a function.} \usage{ splat(flat) } \arguments{ \item{flat}{function to splat} } \value{ a function } \description{ Wraps a function in do.call, so instead of taking multiple arguments, it takes a single named list which will be interpreted as its arguments. } \details{ This is useful when you want to pass a function a row of data frame or array, and don't want to manually pull it apart in your function. } \examples{ hp_per_cyl <- function(hp, cyl, ...) hp / cyl splat(hp_per_cyl)(mtcars[1,]) splat(hp_per_cyl)(mtcars) f <- function(mpg, wt, ...) data.frame(mw = mpg / wt) ddply(mtcars, .(cyl), splat(f)) } plyr/man/round_any.Rd0000644000176000001440000000141512057740032014331 0ustar ripleyusers\name{round_any} \alias{round_any} \title{Round to multiple of any number.} \usage{ round_any(x, accuracy, f = round) } \arguments{ \item{x}{numeric or date-time (POSIXct) vector to round} \item{accuracy}{number to round to; for POSIXct objects, a number of seconds} \item{f}{rounding function: \code{\link{floor}}, \code{\link{ceiling}} or \code{\link{round}}} } \description{ Round to multiple of any number. } \examples{ round_any(135, 10) round_any(135, 100) round_any(135, 25) round_any(135, 10, floor) round_any(135, 100, floor) round_any(135, 25, floor) round_any(135, 10, ceiling) round_any(135, 100, ceiling) round_any(135, 25, ceiling) round_any(Sys.time() + 1:10, 5) round_any(Sys.time() + 1:10, 5, floor) round_any(Sys.time(), 3600) } \keyword{manip} plyr/man/rlply.Rd0000644000176000001440000000210312057740032013470 0ustar ripleyusers\name{rlply} \alias{rlply} \title{Replicate expression and return results in a list.} \usage{ rlply(.n, .expr, .progress = "none") } \arguments{ \item{.n}{number of times to evaluate the expression} \item{.expr}{expression to evaluate} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} } \value{ list of results } \description{ Evalulate expression n times then combine results into a list } \details{ This function runs an expression multiple times, and combines the result into a list. If there are no results, then this function will return a list of length 0 (\code{list()}). This function is equivalent to \code{\link{replicate}}, but will always return results as a list. } \examples{ mods <- rlply(100, lm(y ~ x, data=data.frame(x=rnorm(100), y=rnorm(100)))) hist(laply(mods, function(x) summary(x)$r.squared)) } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \keyword{manip} plyr/man/revalue.Rd0000644000176000001440000000207012057740032013774 0ustar ripleyusers\name{revalue} \alias{revalue} \title{Replace specified values with new values, in a factor or character vector.} \usage{ revalue(x, replace = NULL, warn_missing = TRUE) } \arguments{ \item{x}{factor or character vector to modify} \item{replace}{named character vector, with new values as values, and old values as names.} \item{warn_missing}{print a message if any of the old values are not actually present in \code{x}} } \description{ If \code{x} is a factor, the named levels of the factor will be replaced with the new values. } \details{ This function works only on character vectors and factors, but the related \code{mapvalues} function works on vectors of any type and factors, and instead of a named vector specifying the original and replacement values, it takes two separate vectors } \examples{ x <- c("a", "b", "c") revalue(x, c(a = "A", c = "C")) revalue(x, c("a" = "A", "c" = "C")) y <- factor(c("a", "b", "c", "a")) revalue(y, c(a = "A", c = "C")) } \seealso{ \code{\link{mapvalues}} to replace values with vectors of any type } plyr/man/rename.Rd0000644000176000001440000000137712057740032013611 0ustar ripleyusers\name{rename} \alias{rename} \title{Modify names by name, not position.} \usage{ rename(x, replace, warn_missing = TRUE) } \arguments{ \item{x}{named object to modify} \item{replace}{named character vector, with new names as values, and old names as names.} \item{warn_missing}{print a message if any of the old names are not actually present in \code{x}. Note: x is not altered: To save the result, you need to copy the returned data into a variable.} } \description{ Modify names by name, not position. } \examples{ x <- c("a" = 1, "b" = 2, d = 3, 4) # Rename column d to "c", updating the variable "x" with the result x <- rename(x, replace=c("d" = "c")) x # Rename column "disp" to "displacement" rename(mtcars, c("disp" = "displacement")) } plyr/man/reduce_dim.Rd0000644000176000001440000000027512057740032014436 0ustar ripleyusers\name{reduce_dim} \alias{reduce_dim} \title{Reduce dimensions.} \usage{ reduce_dim(x) } \arguments{ \item{x}{array} } \description{ Remove extraneous dimensions } \keyword{internal} plyr/man/rdply.Rd0000644000176000001440000000212712057740032013466 0ustar ripleyusers\name{rdply} \alias{rdply} \title{Replicate expression and return results in a data frame.} \usage{ rdply(.n, .expr, .progress = "none") } \arguments{ \item{.n}{number of times to evaluate the expression} \item{.expr}{expression to evaluate} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} } \value{ a data frame } \description{ Evalulate expression n times then combine results into a data frame } \details{ This function runs an expression multiple times, and combines the result into a data frame. If there are no results, then this function returns a data frame with zero rows and columns (\code{data.frame()}). This function is equivalent to \code{\link{replicate}}, but will always return results as a data frame. } \examples{ rdply(20, mean(runif(100))) rdply(20, each(mean, var)(runif(100))) rdply(20, data.frame(x = runif(2))) } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \keyword{manip} plyr/man/rbind.fill.Rd0000644000176000001440000000167612057740032014367 0ustar ripleyusers\name{rbind.fill} \alias{rbind.fill} \title{Combine data.frames by row, filling in missing columns.} \usage{ rbind.fill(...) } \arguments{ \item{...}{input data frames to row bind together. The first argument can be a list of data frames, in which case all other arguments are ignored.} } \value{ a single data frame } \description{ \code{rbind}s a list of data frames filling missing columns with NA. } \details{ This is an enhancement to \code{\link{rbind}} that adds in columns that are not present in all inputs, accepts a list of data frames, and operates substantially faster. Column names and types in the output will appear in the order in which they were encountered. No checking is performed to ensure that each column is of consistent type in the inputs. } \examples{ rbind.fill(mtcars[c("mpg", "wt")], mtcars[c("wt", "cyl")]) } \seealso{ Other binding functions: \code{\link{rbind.fill.matrix}} } \keyword{manip} plyr/man/rbind.fill.matrix.Rd0000644000176000001440000000272012057740032015661 0ustar ripleyusers\name{rbind.fill.matrix} \alias{rbind.fill.matrix} \title{Bind matrices by row, and fill missing columns with NA.} \usage{ rbind.fill.matrix(...) } \arguments{ \item{...}{the matrices to rbind. The first argument can be a list of matrices, in which case all other arguments are ignored.} } \value{ a matrix with column names } \description{ The matrices are bound together using their column names or the column indices (in that order of precedence.) Numeric columns may be converted to character beforehand, e.g. using format. If a matrix doesn't have colnames, the column number is used. Note that this means that a column with name \code{"1"} is merged with the first column of a matrix without name and so on. The returned matrix will always have column names. } \details{ Vectors are converted to 1-column matrices. Matrices of factors are not supported. (They are anyways quite inconvenient.) You may convert them first to either numeric or character matrices. If a matrices of different types are merged, then normal covnersion precendence will apply. Row names are ignored. } \examples{ A <- matrix (1:4, 2) B <- matrix (6:11, 2) A B rbind.fill.matrix (A, B) colnames (A) <- c (3, 1) A rbind.fill.matrix (A, B) rbind.fill.matrix (A, 99) } \author{ C. Beleites } \seealso{ \code{\link[base]{rbind}}, \code{\link[base]{cbind}}, \code{\link[plyr]{rbind.fill}} Other binding functions: \code{\link{rbind.fill}} } \keyword{manip} plyr/man/raply.Rd0000644000176000001440000000276012057740032013466 0ustar ripleyusers\name{raply} \alias{raply} \title{Replicate expression and return results in a array.} \usage{ raply(.n, .expr, .progress = "none", .drop = TRUE) } \arguments{ \item{.n}{number of times to evaluate the expression} \item{.expr}{expression to evaluate} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.drop}{should extra dimensions of length 1 be dropped, simplifying the output. Defaults to \code{TRUE}} } \value{ if results are atomic with same type and dimensionality, a vector, matrix or array; otherwise, a list-array (a list with dimensions) } \description{ Evalulate expression n times then combine results into an array } \details{ This function runs an expression multiple times, and combines the result into a data frame. If there are no results, then this function returns a vector of length 0 (\code{vector(0)}). This function is equivalent to \code{\link{replicate}}, but will always return results as a vector, matrix or array. } \examples{ raply(100, mean(runif(100))) raply(100, each(mean, var)(runif(100))) raply(10, runif(4)) raply(10, matrix(runif(4), nrow=2)) # See the central limit theorem in action hist(raply(1000, mean(rexp(10)))) hist(raply(1000, mean(rexp(100)))) hist(raply(1000, mean(rexp(1000)))) } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \keyword{manip} plyr/man/r_ply.Rd0000644000176000001440000000164712057740032013467 0ustar ripleyusers\name{r_ply} \alias{r_ply} \title{Replicate expression and discard results.} \usage{ r_ply(.n, .expr, .progress = "none", .print = FALSE) } \arguments{ \item{.n}{number of times to evaluate the expression} \item{.expr}{expression to evaluate} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.print}{automatically print each result? (default: \code{FALSE})} } \description{ Evalulate expression n times then discard results } \details{ This function runs an expression multiple times, discarding the results. This function is equivalent to \code{\link{replicate}}, but never returns anything } \examples{ r_ply(10, plot(runif(50))) r_ply(25, hist(runif(1000))) } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \keyword{manip} plyr/man/quoted.Rd0000644000176000001440000000332312057740032013634 0ustar ripleyusers\name{.} \alias{.} \alias{is.quoted} \alias{quoted} \title{Quote variables to create a list of unevaluated expressions for later evaluation.} \usage{ .(..., .env = parent.frame()) } \arguments{ \item{...}{unevaluated expressions to be recorded. Specify names if you want the set the names of the resultant variables} \item{.env}{environment in which unbound symbols in \code{...} should be evaluated. Defaults to the environment in which \code{.} was executed.} } \value{ list of symbol and language primitives } \description{ This function is similar to \code{\link{~}} in that it is used to capture the name of variables, not their current value. This is used throughout plyr to specify the names of variables (or more complicated expressions). } \details{ Similar tricks can be performed with \code{\link{substitute}}, but when functions can be called in multiple ways it becomes increasingly tricky to ensure that the values are extracted from the correct frame. Substitute tricks also make it difficult to program against the functions that use them, while the \code{quoted} class provides \code{as.quoted.character} to convert strings to the appropriate data structure. } \examples{ .(a, b, c) .(first = a, second = b, third = c) .(a ^ 2, b - d, log(c)) as.quoted(~ a + b + c) as.quoted(a ~ b + c) as.quoted(c("a", "b", "c")) # Some examples using ddply - look at the column names ddply(mtcars, "cyl", each(nrow, ncol)) ddply(mtcars, ~ cyl, each(nrow, ncol)) ddply(mtcars, .(cyl), each(nrow, ncol)) ddply(mtcars, .(log(cyl)), each(nrow, ncol)) ddply(mtcars, .(logcyl = log(cyl)), each(nrow, ncol)) ddply(mtcars, .(vs + am), each(nrow, ncol)) ddply(mtcars, .(vsam = vs + am), each(nrow, ncol)) } plyr/man/quickdf.Rd0000644000176000001440000000053412057740032013762 0ustar ripleyusers\name{quickdf} \alias{quickdf} \title{Quick data frame.} \usage{ quickdf(list) } \arguments{ \item{list}{list to convert to data frame} } \description{ Experimental version of \code{\link{as.data.frame}} that converts a list to a data frame, but doesn't do any checks to make sure it's a valid format. Much faster. } \keyword{internal} plyr/man/progress_win.Rd0000644000176000001440000000141212057740032015051 0ustar ripleyusers\name{progress_win} \alias{progress_win} \title{Graphical progress bar, powered by Windows.} \usage{ progress_win(title = "plyr progress", ...) } \arguments{ \item{title}{window title} \item{...}{other arguments passed on to \code{winProgressBar}} } \description{ A graphical progress bar displayed in a separate window } \details{ This graphical progress only works on Windows. } \examples{ if(exists("winProgressBar")) { l_ply(1:100, identity, .progress = "win") l_ply(1:100, identity, .progress = progress_win(title="Working...")) } } \seealso{ \code{winProgressBar} for the function that powers this progress bar Other progress bars: \code{\link{progress_none}}, \code{\link{progress_text}}, \code{\link{progress_time}}, \code{\link{progress_tk}} } plyr/man/progress_tk.Rd0000644000176000001440000000161212057740032014674 0ustar ripleyusers\name{progress_tk} \alias{progress_tk} \title{Graphical progress bar, powered by Tk.} \usage{ progress_tk(title = "plyr progress", label = "Working...", ...) } \arguments{ \item{title}{window title} \item{label}{progress bar label (inside window)} \item{...}{other arguments passed on to \code{\link[tcltk]{tkProgressBar}}} } \description{ A graphical progress bar displayed in a Tk window } \details{ This graphical progress will appear in a separate window. } \examples{ \dontrun{ l_ply(1:100, identity, .progress = "tk") l_ply(1:100, identity, .progress = progress_tk(width=400)) l_ply(1:100, identity, .progress = progress_tk(label="")) } } \seealso{ \code{\link[tcltk]{tkProgressBar}} for the function that powers this progress bar Other progress bars: \code{\link{progress_none}}, \code{\link{progress_text}}, \code{\link{progress_time}}, \code{\link{progress_win}} } plyr/man/progress_time.Rd0000644000176000001440000000074712057740032015224 0ustar ripleyusers\name{progress_time} \alias{progress_time} \title{Text progress bar with time.} \usage{ progress_time() } \description{ A textual progress bar that estimates time remaining. It displays the estimated time remaining and, when finished, total duration. } \examples{ l_ply(1:100, function(x) Sys.sleep(.01), .progress = "time") } \seealso{ Other progress bars: \code{\link{progress_none}}, \code{\link{progress_text}}, \code{\link{progress_tk}}, \code{\link{progress_win}} } plyr/man/progress_text.Rd0000644000176000001440000000145512057740032015247 0ustar ripleyusers\name{progress_text} \alias{progress_text} \title{Text progress bar.} \usage{ progress_text(style = 3, ...) } \arguments{ \item{style}{style of text bar, see Details section of \code{\link{txtProgressBar}}} \item{...}{other arugments passed on to \code{\link{txtProgressBar}}} } \description{ A textual progress bar } \details{ This progress bar displays a textual progress bar that works on all platforms. It is a thin wrapper around the built-in \code{\link{setTxtProgressBar}} and can be customised in the same way. } \examples{ l_ply(1:100, identity, .progress = "text") l_ply(1:100, identity, .progress = progress_text(char = "-")) } \seealso{ Other progress bars: \code{\link{progress_none}}, \code{\link{progress_time}}, \code{\link{progress_tk}}, \code{\link{progress_win}} } plyr/man/progress_none.Rd0000644000176000001440000000075712057740032015226 0ustar ripleyusers\name{progress_none} \alias{progress_none} \title{Null progress bar} \usage{ progress_none() } \description{ A progress bar that does nothing } \details{ This the default progress bar used by plyr functions. It's very simple to understand - it does nothing! } \examples{ l_ply(1:100, identity, .progress = "none") } \seealso{ Other progress bars: \code{\link{progress_text}}, \code{\link{progress_time}}, \code{\link{progress_tk}}, \code{\link{progress_win}} } \keyword{internal} plyr/man/print.split.Rd0000644000176000001440000000040312057740032014615 0ustar ripleyusers\name{print.split} \alias{print.split} \title{Print split.} \usage{ \method{print}{split} (x, ...) } \arguments{ \item{x}{object to print} \item{...}{unused} } \description{ Don't print labels, so it appears like a regular list } \keyword{internal} plyr/man/print.quoted.Rd0000644000176000001440000000032312057740032014764 0ustar ripleyusers\name{print.quoted} \alias{print.quoted} \title{Print quoted variables.} \usage{ \method{print}{quoted} (x, ...) } \description{ Display the \code{\link{str}}ucture of quoted variables } \keyword{internal} plyr/man/plyr.Rd0000644000176000001440000000505512057740032013325 0ustar ripleyusers\docType{package} \name{plyr} \alias{plyr} \alias{plyr-package} \title{plyr: the split-apply-combine paradigm for R.} \description{ The plyr package is a set of clean and consistent tools that implement the split-apply-combine pattern in R. This is an extremely common pattern in data analysis: you solve a complex problem by breaking it down into small pieces, doing something to each piece and then combining the results back together again. } \details{ The plyr functions are named according to what sort of data structure they split up and what sort of data structure they return: \describe{ \item{a}{array} \item{l}{list} \item{d}{data.frame} \item{m}{multiple inputs} \item{r}{repeat multiple times} \item{_}{nothing} } So \code{\link{ddply}} takes a data frame as input and returns a data frame as output, and \code{\link{l_ply}} takes a list as input and returns nothing as output. } \section{Row names}{ By design, no plyr function will preserve row names - in general it is too hard to know what should be done with them for many of the operations supported by plyr. If you want to preserve row names, use \code{\link{name_rows}} to convert them into an explicit column in your data frame, perform the plyr operations, and then use \code{\link{name_rows}} again to convert the column back into row names. } \section{Helpers}{ Plyr also provides a set of helper functions for common data analysis problems: \itemize{ \item \code{\link{arrange}}: re-order the rows of a data frame by specifying the columns to order by \item \code{\link{mutate}}: add new columns or modifying existing columns, like \code{\link{transform}}, but new columns can refer to other columns that you just created. \item \code{\link{summarise}}: like \code{\link{mutate}} but create a new data frame, not preserving any columns in the old data frame. \item \code{\link{join}}: an adapation of \code{\link{merge}} which is more similar to SQL, and has a much faster implementation if you only want to find the first match. \item \code{\link{match_df}}: a version of \code{\link{join}} that instead of returning the two tables combined together, only returns the rows in the first table that match the second. \item \code{\link{colwise}}: make any function work colwise on a dataframe \item \code{\link{rename}}: easily rename columns in a data frame \item \code{\link{round_any}}: round a number to any degree of precision \item \code{\link{count}}: quickly count unique combinations and return return as a data frame. } } plyr/man/ozone.Rd0000644000176000001440000000224212057740032013464 0ustar ripleyusers\docType{data} \name{ozone} \alias{ozone} \title{Monthly ozone measurements over Central America.} \format{A 24 x 24 x 72 numeric array} \description{ This data set is a subset of the data from the 2006 ASA Data expo challenge, \url{http://stat-computing.org/dataexpo/2006/}. The data are monthly ozone averages on a very coarse 24 by 24 grid covering Central America, from Jan 1995 to Dec 2000. The data is stored in a 3d area with the first two dimensions representing latitude and longitude, and the third representing time. } \examples{ value <- ozone[1, 1, ] time <- 1:72 month.abbr <- c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec") month <- factor(rep(month.abbr, length = 72), levels = month.abbr) year <- rep(1:6, each = 12) deseasf <- function(value) lm(value ~ month - 1) models <- alply(ozone, 1:2, deseasf) coefs <- laply(models, coef) dimnames(coefs)[[3]] <- month.abbr names(dimnames(coefs))[3] <- "month" deseas <- laply(models, resid) dimnames(deseas)[[3]] <- 1:72 names(dimnames(deseas))[3] <- "time" dim(coefs) dim(deseas) } \references{ \url{http://stat-computing.org/dataexpo/2006/} } \keyword{datasets} plyr/man/nunique.Rd0000644000176000001440000000035412057740032014020 0ustar ripleyusers\name{nunique} \alias{nunique} \title{Number of unique values.} \usage{ nunique(x) } \arguments{ \item{x}{vector} } \description{ Calculate number of unique values of a variable as efficiently as possible. } \keyword{internal} plyr/man/names.quoted.Rd0000644000176000001440000000056312057740032014741 0ustar ripleyusers\name{names.quoted} \alias{names.quoted} \title{Compute names of quoted variables.} \usage{ \method{names}{quoted} (x) } \description{ Figure out names of quoted variables, using specified names if they exist, otherwise converting the values to character strings. This may create variable names that can only be accessed using \code{``}. } \keyword{internal} plyr/man/name_rows.Rd0000644000176000001440000000131012057740032014317 0ustar ripleyusers\name{name_rows} \alias{name_rows} \title{Toggle row names between explicit and implicit.} \usage{ name_rows(df) } \arguments{ \item{df}{a data.frame, with either \code{rownames}, or a column called \code{.rownames}.} } \description{ Plyr functions ignore row names, so this function provides a way to preserve them by converting them to an explicit column in the data frame. After the plyr operation, you can then apply \code{name_rows} again to convert back from the explicit column to the implicit \code{rownames}. } \examples{ name_rows(mtcars) name_rows(name_rows(mtcars)) df <- data.frame(a = sample(10)) arrange(df, a) arrange(name_rows(df), a) name_rows(arrange(name_rows(df), a)) } plyr/man/mutate.Rd0000644000176000001440000000223512057740032013633 0ustar ripleyusers\name{mutate} \alias{mutate} \title{Mutate a data frame by adding new or replacing existing columns.} \usage{ mutate(.data, ...) } \arguments{ \item{.data}{the data frame to transform} \item{...}{named parameters giving definitions of new columns.} } \description{ This function is very similar to \code{\link{transform}} but it executes the transformations iteratively so that later transformations can use the columns created by earlier transformations. Like transform, unnamed components are silently dropped. } \details{ Mutate seems to be considerably faster than transform for large data frames. } \examples{ # Examples from transform mutate(airquality, Ozone = -Ozone) mutate(airquality, new = -Ozone, Temp = (Temp - 32) / 1.8) # Things transform can't do mutate(airquality, Temp = (Temp - 32) / 1.8, OzT = Ozone / Temp) # mutate is rather faster than transform system.time(transform(baseball, avg_ab = ab / g)) system.time(mutate(baseball, avg_ab = ab / g)) } \seealso{ \code{\link{subset}}, \code{\link{summarise}}, \code{\link{arrange}}. For another somewhat different approach to solving the same problem, see \code{\link{within}}. } plyr/man/mlply.Rd0000644000176000001440000000507412057740032013475 0ustar ripleyusers\name{mlply} \alias{mlply} \title{Call function with arguments in array or data frame, returning a list.} \usage{ mlply(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{matrix or data frame to use as source of arguments} \item{.expand}{should output be 1d (expand = FALSE), with an element for each row; or nd (expand = TRUE), with a dimension for each variable.} } \value{ list of results } \description{ Call a multi-argument function with values taken from columns of an data frame or array, and combine results into a list. } \details{ The \code{m*ply} functions are the \code{plyr} version of \code{mapply}, specialised according to the type of output they produce. These functions are just a convenient wrapper around \code{a*ply} with \code{margins = 1} and \code{.fun} wrapped in \code{\link{splat}}. } \section{Input}{ Call a multi-argument function with values taken from columns of an data frame or array } \section{Output}{ If there are no results, then this function will return a list of length 0 (\code{list()}). } \examples{ mlply(cbind(1:4, 4:1), rep) mlply(cbind(1:4, times = 4:1), rep) mlply(cbind(1:4, 4:1), seq) mlply(cbind(1:4, length = 4:1), seq) mlply(cbind(1:4, by = 4:1), seq, to = 20) } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ Other list output: \code{\link{alply}}, \code{\link{dlply}}, \code{\link{llply}} Other multiple arguments input: \code{\link{m_ply}}, \code{\link{maply}}, \code{\link{mdply}} } \keyword{manip} plyr/man/mdply.Rd0000644000176000001440000000601012057740032013454 0ustar ripleyusers\name{mdply} \alias{mdply} \title{Call function with arguments in array or data frame, returning a data frame.} \usage{ mdply(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{matrix or data frame to use as source of arguments} \item{.expand}{should output be 1d (expand = FALSE), with an element for each row; or nd (expand = TRUE), with a dimension for each variable.} } \value{ A data frame, as described in the output section. } \description{ Call a multi-argument function with values taken from columns of an data frame or array, and combine results into a data frame } \details{ The \code{m*ply} functions are the \code{plyr} version of \code{mapply}, specialised according to the type of output they produce. These functions are just a convenient wrapper around \code{a*ply} with \code{margins = 1} and \code{.fun} wrapped in \code{\link{splat}}. } \section{Input}{ Call a multi-argument function with values taken from columns of an data frame or array } \section{Output}{ The most unambiguous behaviour is achieved when \code{.fun} returns a data frame - in that case pieces will be combined with \code{\link{rbind.fill}}. If \code{.fun} returns an atomic vector of fixed length, it will be \code{rbind}ed together and converted to a data frame. Any other values will result in an error. If there are no results, then this function will return a data frame with zero rows and columns (\code{data.frame()}). } \examples{ mdply(data.frame(mean = 1:5, sd = 1:5), rnorm, n = 2) mdply(expand.grid(mean = 1:5, sd = 1:5), rnorm, n = 2) mdply(cbind(mean = 1:5, sd = 1:5), rnorm, n = 5) mdply(cbind(mean = 1:5, sd = 1:5), as.data.frame(rnorm), n = 5) } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ Other data frame output: \code{\link{adply}}, \code{\link{ddply}}, \code{\link{ldply}} Other multiple arguments input: \code{\link{m_ply}}, \code{\link{maply}}, \code{\link{mlply}} } \keyword{manip} plyr/man/match_df.Rd0000644000176000001440000000310112057740032014072 0ustar ripleyusers\name{match_df} \alias{match_df} \title{Extract matching rows of a data frame.} \usage{ match_df(x, y, on = NULL) } \arguments{ \item{x}{data frame to subset.} \item{y}{data frame defining matching rows.} \item{on}{variables to match on - by default will use all variables common to both data frames.} } \value{ a data frame } \description{ Match works in the same way as join, but instead of return the combined dataset, it only returns the matching rows from the first dataset. This is particularly useful when you've summarised the data in some way and want to subset the original data by a characteristic of the subset. } \details{ \code{match_df} shares the same semantics as \code{\link{join}}, not \code{\link{match}}: \itemize{ \item the match criterion is \code{==}, not \code{\link{identical}}). \item it doesn't work for columns that are not atomic vectors \item if there are no matches, the row will be omitted' } } \examples{ # count the occurrences of each id in the baseball dataframe, then get the subset with a freq >25 longterm <- subset(count(baseball, "id"), freq > 25) # longterm # id freq # 30 ansonca01 27 # 48 baineha01 27 # ... # Select only rows from these longterm players from the baseball dataframe # (match would default to match on shared column names, but here was explicitly set "id") bb_longterm <- match_df(baseball, longterm, on="id") bb_longterm[1:5,] } \seealso{ \code{\link{join}} to combine the columns from both x and y and \code{\link{match}} for the base function selecting matching items } plyr/man/mapvalues.Rd0000644000176000001440000000246312057740032014334 0ustar ripleyusers\name{mapvalues} \alias{mapvalues} \title{Replace specified values with new values, in a vector or factor.} \usage{ mapvalues(x, from, to, warn_missing = TRUE) } \arguments{ \item{x}{the factor or vector to modify} \item{from}{a vector of the items to replace} \item{to}{a vector of replacement values} \item{warn_missing}{print a message if any of the old values are not actually present in \code{x}} } \description{ Item in \code{x} that match items \code{from} will be replaced by items in \code{to}, matched by position. For example, items in \code{x} that match the first element in \code{from} will be replaced by the first element of \code{to}. } \details{ If \code{x} is a factor, the matching levels of the factor will be replaced with the new values. The related \code{revalue} function works only on character vectors and factors, but this function works on vectors of any type and factors. } \examples{ x <- c("a", "b", "c") mapvalues(x, c("a", "c"), c("A", "C")) # Works on factors y <- factor(c("a", "b", "c", "a")) mapvalues(y, c("a", "c"), c("A", "C")) # Works on numeric vectors z <- c(1, 4, 5, 9) mapvalues(z, from = c(1, 5, 9), to = c(10, 50, 90)) } \seealso{ \code{\link{revalue}} to do the same thing but with a single named vector instead of two separate vectors. } plyr/man/maply.Rd0000644000176000001440000000546012057740032013461 0ustar ripleyusers\name{maply} \alias{maply} \title{Call function with arguments in array or data frame, returning an array.} \usage{ maply(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{matrix or data frame to use as source of arguments} \item{.expand}{should output be 1d (expand = FALSE), with an element for each row; or nd (expand = TRUE), with a dimension for each variable.} \item{.drop}{should extra dimensions of length 1 in the output be dropped, simplifying the output. Defaults to \code{TRUE}} } \value{ if results are atomic with same type and dimensionality, a vector, matrix or array; otherwise, a list-array (a list with dimensions) } \description{ Call a multi-argument function with values taken from columns of an data frame or array, and combine results into an array } \details{ The \code{m*ply} functions are the \code{plyr} version of \code{mapply}, specialised according to the type of output they produce. These functions are just a convenient wrapper around \code{a*ply} with \code{margins = 1} and \code{.fun} wrapped in \code{\link{splat}}. } \section{Input}{ Call a multi-argument function with values taken from columns of an data frame or array } \section{Output}{ If there are no results, then this function will return a vector of length 0 (\code{vector()}). } \examples{ maply(cbind(mean = 1:5, sd = 1:5), rnorm, n = 5) maply(expand.grid(mean = 1:5, sd = 1:5), rnorm, n = 5) maply(cbind(1:5, 1:5), rnorm, n = 5) } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ Other array output: \code{\link{aaply}}, \code{\link{daply}}, \code{\link{laply}} Other multiple arguments input: \code{\link{m_ply}}, \code{\link{mdply}}, \code{\link{mlply}} } \keyword{manip} plyr/man/m_ply.Rd0000644000176000001440000000501712057740032013455 0ustar ripleyusers\name{m_ply} \alias{m_ply} \title{Call function with arguments in array or data frame, discarding results.} \usage{ m_ply(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .print = FALSE, .parallel = FALSE, .paropts = NULL) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{matrix or data frame to use as source of arguments} \item{.expand}{should output be 1d (expand = FALSE), with an element for each row; or nd (expand = TRUE), with a dimension for each variable.} \item{.print}{automatically print each result? (default: \code{FALSE})} } \value{ Nothing } \description{ Call a multi-argument function with values taken from columns of an data frame or array, and discard results into a list. } \details{ The \code{m*ply} functions are the \code{plyr} version of \code{mapply}, specialised according to the type of output they produce. These functions are just a convenient wrapper around \code{a*ply} with \code{margins = 1} and \code{.fun} wrapped in \code{\link{splat}}. } \section{Input}{ Call a multi-argument function with values taken from columns of an data frame or array } \section{Output}{ All output is discarded. This is useful for functions that you are calling purely for their side effects like displaying plots or saving output. } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ Other multiple arguments input: \code{\link{maply}}, \code{\link{mdply}}, \code{\link{mlply}} Other no output: \code{\link{a_ply}}, \code{\link{d_ply}}, \code{\link{l_ply}} } \keyword{manip} plyr/man/loop_apply.Rd0000644000176000001440000000061612057740032014513 0ustar ripleyusers\name{loop_apply} \alias{loop_apply} \title{Loop apply} \usage{ loop_apply(n, f, env = parent.frame()) } \arguments{ \item{n}{length of sequence} \item{f}{function to apply to each integer} \item{env}{environment in which to evaluate function} } \description{ An optimised version of lapply for the special case of operating on \code{seq_len(n)} } \keyword{internal} \keyword{manip} plyr/man/llply.Rd0000644000176000001440000000416712057740032013476 0ustar ripleyusers\name{llply} \alias{llply} \title{Split list, apply function, and return results in a list.} \usage{ llply(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{list to be processed} } \value{ list of results } \description{ For each element of a list, apply function, keeping results as a list. } \details{ \code{llply} is equivalent to \code{\link{lapply}} except that it will preserve labels and can display a progress bar. } \section{Input}{ This function splits lists by elements. } \section{Output}{ If there are no results, then this function will return a list of length 0 (\code{list()}). } \examples{ llply(llply(mtcars, round), table) llply(baseball, summary) # Examples from ?lapply x <- list(a = 1:10, beta = exp(-3:3), logic = c(TRUE,FALSE,FALSE,TRUE)) llply(x, mean) llply(x, quantile, probs = 1:3/4) } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ Other list input: \code{\link{l_ply}}, \code{\link{laply}}, \code{\link{ldply}} Other list output: \code{\link{alply}}, \code{\link{dlply}}, \code{\link{mlply}} } \keyword{manip} plyr/man/list_to_vector.Rd0000644000176000001440000000054712057740032015377 0ustar ripleyusers\name{list_to_vector} \alias{list_to_vector} \title{List to vector.} \usage{ list_to_vector(res) } \arguments{ \item{res}{list of input data} } \description{ Reduce/simplify a list of homogenous objects to a vector } \seealso{ Other list simplification functions: \code{\link{list_to_array}}, \code{\link{list_to_dataframe}} } \keyword{internal} plyr/man/list_to_dataframe.Rd0000644000176000001440000000106112057740032016011 0ustar ripleyusers\name{list_to_dataframe} \alias{list_to_dataframe} \title{List to data frame.} \usage{ list_to_dataframe(res, labels = NULL) } \arguments{ \item{res}{list of input data} \item{labels}{a data frame of labels, one row for each element of res} } \description{ Reduce/simplify a list of homogenous objects to a data frame. All \code{NULL} entries are removed. Remaining entries must be all atomic or all data frames. } \seealso{ Other list simplification functions: \code{\link{list_to_array}}, \code{\link{list_to_vector}} } \keyword{internal} plyr/man/list_to_array.Rd0000644000176000001440000000104012057740032015200 0ustar ripleyusers\name{list_to_array} \alias{list_to_array} \title{List to array.} \usage{ list_to_array(res, labels = NULL, .drop = FALSE) } \arguments{ \item{res}{list of input data} \item{labels}{a data frame of labels, one row for each element of res} \item{.drop}{should extra dimensions be dropped (TRUE) or preserved (FALSE)} } \description{ Reduce/simplify a list of homogenous objects to an array } \seealso{ Other list simplification functions: \code{\link{list_to_dataframe}}, \code{\link{list_to_vector}} } \keyword{internal} plyr/man/liply.Rd0000644000176000001440000000170712057740032013470 0ustar ripleyusers\name{liply} \alias{liply} \title{Experimental iterator based version of llply.} \usage{ liply(.iterator, .fun = NULL, ...) } \arguments{ \item{.iterator}{iterator object} \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} } \description{ Because iterators do not have known length, \code{liply} starts by allocating an output list of length 50, and then doubles that length whenever it runs out of space. This gives O(n ln n) performance rather than the O(n ^ 2) performance from the naive strategy of growing the list each time. } \examples{ if(require("iterators")) { system.time(dlply(baseball, "id", summarise, mean_rbi = mean(rbi))) system.time({ baseball_id <- isplit2(baseball, baseball$id) liply(baseball_id, summarise, mean_rbi = mean(rbi, na.rm = TRUE)) }) # Iterators get used up: liply(baseball_id, summarise, mean_rbi = mean(rbi, na.rm = TRUE)) } } \keyword{manip} plyr/man/ldply.Rd0000644000176000001440000000426412057740032013464 0ustar ripleyusers\name{ldply} \alias{ldply} \title{Split list, apply function, and return results in a data frame.} \usage{ ldply(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{list to be processed} } \value{ A data frame, as described in the output section. } \description{ For each element of a list, apply function then combine results into a data frame. } \section{Input}{ This function splits lists by elements. } \section{Output}{ The most unambiguous behaviour is achieved when \code{.fun} returns a data frame - in that case pieces will be combined with \code{\link{rbind.fill}}. If \code{.fun} returns an atomic vector of fixed length, it will be \code{rbind}ed together and converted to a data frame. Any other values will result in an error. If there are no results, then this function will return a data frame with zero rows and columns (\code{data.frame()}). } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ Other data frame output: \code{\link{adply}}, \code{\link{ddply}}, \code{\link{mdply}} Other list input: \code{\link{l_ply}}, \code{\link{laply}}, \code{\link{llply}} } \keyword{manip} plyr/man/laply.Rd0000644000176000001440000000476712057740032013471 0ustar ripleyusers\name{laply} \alias{laply} \title{Split list, apply function, and return results in an array.} \usage{ laply(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{list to be processed} \item{.drop}{should extra dimensions of length 1 in the output be dropped, simplifying the output. Defaults to \code{TRUE}} } \value{ if results are atomic with same type and dimensionality, a vector, matrix or array; otherwise, a list-array (a list with dimensions) } \description{ For each element of a list, apply function then combine results into an array. } \details{ \code{laply} is similar in spirit to \code{\link{sapply}} except that it will always return an array, and the output is transposed with respect \code{sapply} - each element of the list corresponds to a row, not a column. } \section{Input}{ This function splits lists by elements. } \section{Output}{ If there are no results, then this function will return a vector of length 0 (\code{vector()}). } \examples{ laply(baseball, is.factor) # cf ldply(baseball, is.factor) colwise(is.factor)(baseball) laply(seq_len(10), identity) laply(seq_len(10), rep, times = 4) laply(seq_len(10), matrix, nrow = 2, ncol = 2) } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ Other array output: \code{\link{aaply}}, \code{\link{daply}}, \code{\link{maply}} Other list input: \code{\link{l_ply}}, \code{\link{ldply}}, \code{\link{llply}} } \keyword{manip} plyr/man/l_ply.Rd0000644000176000001440000000362012057740032013452 0ustar ripleyusers\name{l_ply} \alias{l_ply} \title{Split list, apply function, and discard results.} \usage{ l_ply(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE, .print = FALSE, .parallel = FALSE, .paropts = NULL) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{list to be processed} \item{.print}{automatically print each result? (default: \code{FALSE})} } \value{ Nothing } \description{ For each element of a list, apply function and discard results } \section{Input}{ This function splits lists by elements. } \section{Output}{ All output is discarded. This is useful for functions that you are calling purely for their side effects like displaying plots or saving output. } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ Other list input: \code{\link{laply}}, \code{\link{ldply}}, \code{\link{llply}} Other no output: \code{\link{a_ply}}, \code{\link{d_ply}}, \code{\link{m_ply}} } \keyword{manip} plyr/man/join_all.Rd0000644000176000001440000000162012057740032014120 0ustar ripleyusers\name{join_all} \alias{join_all} \title{Recursively join a list of data frames.} \usage{ join_all(dfs, by = NULL, type = "left", match = "all") } \arguments{ \item{dfs}{A list of data frames.} \item{by}{character vector of variable names to join by. If omitted, will match on all common variables.} \item{type}{type of join: left (default), right, inner or full. See details for more information.} \item{match}{how should duplicate ids be matched? Either match just the \code{"first"} matching row, or match \code{"all"} matching rows. Defaults to \code{"all"} for compatibility with merge, but \code{"first"} is significantly faster.} } \description{ Recursively join a list of data frames. } \examples{ dfs <- list( a = data.frame(x = 1:10, a = runif(10)), b = data.frame(x = 1:10, b = runif(10)), c = data.frame(x = 1:10, c = runif(10)) ) join_all(dfs) join_all(dfs, "x") } plyr/man/join.Rd0000644000176000001440000000353312057740032013275 0ustar ripleyusers\name{join} \alias{join} \title{Join two data frames together.} \usage{ join(x, y, by = NULL, type = "left", match = "all") } \arguments{ \item{x}{data frame} \item{y}{data frame} \item{by}{character vector of variable names to join by. If omitted, will match on all common variables.} \item{type}{type of join: left (default), right, inner or full. See details for more information.} \item{match}{how should duplicate ids be matched? Either match just the \code{"first"} matching row, or match \code{"all"} matching rows. Defaults to \code{"all"} for compatibility with merge, but \code{"first"} is significantly faster.} } \description{ Join, like merge, is designed for the types of problems where you would use a sql join. } \details{ The four join types return: \itemize{ \item \code{inner}: only rows with matching keys in both x and y \item \code{left}: all rows in x, adding matching columns from y \item \code{right}: all rows in y, adding matching columns from x \item \code{full}: all rows in x with matching columns in y, then the rows of y that don't match x. } Note that from plyr 1.5, \code{join} will (by default) return all matches, not just the first match, as it did previously. Unlike merge, preserves the order of x no matter what join type is used. If needed, rows from y will be added to the bottom. Join is often faster than merge, although it is somewhat less featureful - it currently offers no way to rename output or merge on different variables in the x and y data frames. } \examples{ first <- ddply(baseball, "id", summarise, first = min(year)) system.time(b2 <- merge(baseball, first, by = "id", all.x = TRUE)) system.time(b3 <- join(baseball, first, by = "id")) b2 <- arrange(b2, id, year, stint) b3 <- arrange(b3, id, year, stint) stopifnot(all.equal(b2, b3)) } \keyword{manip} plyr/man/join.keys.Rd0000644000176000001440000000056412057740032014250 0ustar ripleyusers\name{join.keys} \alias{join.keys} \title{Join keys. Given two data frames, create a unique key for each row.} \usage{ join.keys(x, y, by) } \arguments{ \item{x}{data frame} \item{y}{data frame} \item{by}{character vector of variable names to join by} } \description{ Join keys. Given two data frames, create a unique key for each row. } \keyword{internal} plyr/man/isplit2.Rd0000644000176000001440000000033412057740032013720 0ustar ripleyusers\name{isplit2} \alias{isplit2} \title{Split iterator that returns values, not indices.} \usage{ isplit2(x, f, drop = FALSE, ...) } \description{ Split iterator that returns values, not indices. } \keyword{internal} plyr/man/is.formula.Rd0000644000176000001440000000031112057740032014404 0ustar ripleyusers\name{is.formula} \alias{is.formula} \title{Is a formula? Checks if argument is a formula} \usage{ is.formula(x) } \description{ Is a formula? Checks if argument is a formula } \keyword{internal} plyr/man/is.discrete.Rd0000644000176000001440000000052312057740032014546 0ustar ripleyusers\name{is.discrete} \alias{is.discrete} \title{Determine if a vector is discrete.} \usage{ is.discrete(x) } \arguments{ \item{x}{vector to test} } \description{ A discrete vector is a factor or a character vector } \examples{ is.discrete(1:10) is.discrete(c("a", "b", "c")) is.discrete(factor(c("a", "b", "c"))) } \keyword{internal} plyr/man/indexed_df.Rd0000644000176000001440000000062412057740032014425 0ustar ripleyusers\name{indexed_df} \alias{indexed_df} \title{An indexed data frame.} \usage{ indexed_df(data, index, vars) } \arguments{ \item{env}{environment containing data frame} \item{index}{list of indices} \item{vars}{a character vector giving the variables used for subsetting} } \description{ Create a indexed list, a space efficient way of indexing into a large data frame } \keyword{internal} plyr/man/indexed_array.Rd0000644000176000001440000000062212057740032015150 0ustar ripleyusers\name{indexed_array} \alias{[[.indexed_array} \alias{indexed_array} \alias{length.indexed_array} \alias{names.indexed_array} \title{An indexed array.} \usage{ indexed_array(env, index) } \arguments{ \item{env}{environment containing data frame} \item{index}{list of indices} } \description{ Create a indexed array, a space efficient way of indexing into a large array. } \keyword{internal} plyr/man/idata.frame.Rd0000644000176000001440000000133212057740032014504 0ustar ripleyusers\name{idata.frame} \alias{idata.frame} \title{Construct an immutable data frame.} \usage{ idata.frame(df) } \arguments{ \item{df}{a data frame} } \value{ an immutable data frame } \description{ An immutable data frame works like an ordinary data frame, except that when you subset it, it returns a reference to the original data frame, not a a copy. This makes subsetting substantially faster and has a big impact when you are working with large datasets with many groups. } \details{ This method is still a little experimental, so please let me know if you run into any problems. } \examples{ system.time(dlply(baseball, "id", nrow)) system.time(dlply(idata.frame(baseball), "id", nrow)) } \keyword{manip} plyr/man/id_var.Rd0000644000176000001440000000024112057740032013573 0ustar ripleyusers\name{id_var} \alias{id_var} \title{Numeric id for a vector.} \usage{ id_var(x, drop = FALSE) } \description{ Numeric id for a vector. } \keyword{internal} plyr/man/id.Rd0000644000176000001440000000116012057740032012724 0ustar ripleyusers\name{id} \alias{id} \alias{ninteraction} \title{Compute a unique numeric id for each unique row in a data frame.} \usage{ id(.variables, drop = FALSE) } \arguments{ \item{.variables}{list of variables} \item{drop}{drop unusued factor levels?} } \value{ a numeric vector with attribute n, giving total number of possibilities } \description{ Properties: \itemize{ \item \code{order(id)} is equivalent to \code{do.call(order, df)} \item rows containing the same data have the same value \item if \code{drop = FALSE} then room for all possibilites } } \seealso{ \code{\link{id_var}} } \keyword{internal} plyr/man/here.Rd0000644000176000001440000000141612057740032013257 0ustar ripleyusers\name{here} \alias{here} \title{Capture current evaluation context.} \usage{ here(f) } \arguments{ \item{f}{a function that does non-standard evaluation} } \description{ This function captures the current context, making it easier to use \code{**ply} with functions that do special evaluation and need access to the environment where ddply was called from. } \examples{ df <- data.frame(a = rep(c("a","b"), each = 10), b = 1:20) f1 <- function(label) { ddply(df, "a", mutate, label = paste(label, b)) } \dontrun{f1("name:")} # Doesn't work because mutate can't find label in the current scope f2 <- function(label) { ddply(df, "a", here(mutate), label = paste(label, b)) } f2("name:") # Works :) } \author{ Peter Meilstrup, \url{https://github.com/crowding} } plyr/man/get-split.Rd0000644000176000001440000000041012057740032014235 0ustar ripleyusers\name{[.split} \alias{[.split} \title{Subset splits.} \usage{ \method{[}{split} (x, i, ...) } \arguments{ \item{x}{split object} \item{i}{index} \item{...}{unused} } \description{ Subset splits, ensuring that labels keep matching } \keyword{internal} plyr/man/failwith.Rd0000644000176000001440000000105312057740032014140 0ustar ripleyusers\name{failwith} \alias{failwith} \title{Fail with specified value.} \usage{ failwith(default = NULL, f, quiet = FALSE) } \arguments{ \item{default}{default value} \item{f}{function} \item{quiet}{all error messages be suppressed?} } \value{ a function } \description{ Modify a function so that it returns a default value when there is an error. } \examples{ f <- function(x) if (x == 1) stop("Error!") else 1 \dontrun{ f(1) f(2) } safef <- failwith(NULL, f) safef(1) safef(2) } \seealso{ \code{\link{try_default}} } \keyword{debugging} plyr/man/eval.quoted.Rd0000644000176000001440000000061512057740032014563 0ustar ripleyusers\name{eval.quoted} \alias{eval.quoted} \title{Evaluate a quoted list of variables.} \usage{ eval.quoted(exprs, envir = NULL, enclos = NULL, try = FALSE) } \arguments{ \item{expr}{quoted object to evalution} \item{try}{if TRUE, return \code{NULL} if evaluation unsuccesful} } \value{ a list } \description{ Evaluates quoted variables in specified environment } \keyword{internal} plyr/man/empty.Rd0000644000176000001440000000033512057740032013471 0ustar ripleyusers\name{empty} \alias{empty} \title{Check if a data frame is empty.} \usage{ empty(df) } \arguments{ \item{df}{data frame to check} } \description{ Empty if it's null or it has 0 rows or columns } \keyword{internal} plyr/man/each.Rd0000644000176000001440000000162412057740032013235 0ustar ripleyusers\name{each} \alias{each} \title{Aggregate multiple functions into a single function.} \usage{ each(...) } \arguments{ \item{...}{functions to combine. each function should produce a single number as output} } \description{ Combine multiple functions into a single function returning a named vector of outputs. Note: you cannot supply additional parameters for the summary functions } \examples{ # Call min() and max() on the vector 1:10 each(min, max)(1:10) # This syntax looks a little different. It is shorthand for the # the following: f<- each(min, max) f(1:10) # Three equivalent ways to call min() and max() on the vector 1:10 each("min", "max")(1:10) each(c("min", "max"))(1:10) each(c(min, max))(1:10) # Call length(), min() and max() on a random normal vector each(length, mean, var)(rnorm(100)) } \seealso{ \code{\link{summarise}} for applying summary functions to data } \keyword{manip} plyr/man/dlply.Rd0000644000176000001440000000476012057740032013465 0ustar ripleyusers\name{dlply} \alias{dlply} \title{Split data frame, apply function, and return results in a list.} \usage{ dlply(.data, .variables, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{data frame to be processed} \item{.variables}{variables to split data frame by, as \code{\link{as.quoted}} variables, a formula or character vector} \item{.drop}{should combinations of variables that do not appear in the input data be preserved (FALSE) or dropped (TRUE, default)} } \value{ list of results } \description{ For each subset of a data frame, apply function then combine results into a list. \code{dlply} is similar to \code{\link{by}} except that the results are returned in a different format. } \section{Input}{ This function splits data frames by variables. } \section{Output}{ If there are no results, then this function will return a list of length 0 (\code{list()}). } \examples{ linmod <- function(df) { lm(rbi ~ year, data = mutate(df, year = year - min(year))) } models <- dlply(baseball, .(id), linmod) models[[1]] coef <- ldply(models, coef) with(coef, plot(`(Intercept)`, year)) qual <- laply(models, function(mod) summary(mod)$r.squared) hist(qual) } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ Other data frame input: \code{\link{d_ply}}, \code{\link{daply}}, \code{\link{ddply}} Other list output: \code{\link{alply}}, \code{\link{llply}}, \code{\link{mlply}} } \keyword{manip} plyr/man/dims.Rd0000644000176000001440000000027412057740032013271 0ustar ripleyusers\name{dims} \alias{dims} \title{Number of dimensions.} \usage{ dims(x) } \arguments{ \item{x}{array} } \description{ Number of dimensions of an array or vector } \keyword{internal} plyr/man/desc.Rd0000644000176000001440000000054612057740032013255 0ustar ripleyusers\name{desc} \alias{desc} \title{Descending order.} \usage{ desc(x) } \arguments{ \item{x}{vector to transform} } \description{ Transform a vector into a format that will be sorted in descending order. } \examples{ desc(1:10) desc(factor(letters)) first_day <- seq(as.Date("1910/1/1"), as.Date("1920/1/1"), "years") desc(first_day) } \keyword{manip} plyr/man/defaults.Rd0000644000176000001440000000037212057740032014143 0ustar ripleyusers\name{defaults} \alias{defaults} \title{Set defaults.} \usage{ defaults(x, y) } \arguments{ \item{x}{list of values} \item{y}{defaults} } \description{ Convient method for combining a list of values with their defaults. } \keyword{manip} plyr/man/ddply.Rd0000644000176000001440000000676712057740032013466 0ustar ripleyusers\name{ddply} \alias{ddply} \title{Split data frame, apply function, and return results in a data frame.} \usage{ ddply(.data, .variables, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{data frame to be processed} \item{.variables}{variables to split data frame by, as \code{\link{as.quoted}} variables, a formula or character vector} \item{.drop}{should combinations of variables that do not appear in the input data be preserved (FALSE) or dropped (TRUE, default)} } \value{ A data frame, as described in the output section. } \description{ For each subset of a data frame, apply function then combine results into a data frame. } \section{Input}{ This function splits data frames by variables. } \section{Output}{ The most unambiguous behaviour is achieved when \code{.fun} returns a data frame - in that case pieces will be combined with \code{\link{rbind.fill}}. If \code{.fun} returns an atomic vector of fixed length, it will be \code{rbind}ed together and converted to a data frame. Any other values will result in an error. If there are no results, then this function will return a data frame with zero rows and columns (\code{data.frame()}). } \examples{ # Summarize a dataset by two variables require(plyr) dfx <- data.frame( group = c(rep('A', 8), rep('B', 15), rep('C', 6)), sex = sample(c("M", "F"), size = 29, replace = TRUE), age = runif(n = 29, min = 18, max = 54) ) # Note the use of the '.' function to allow # group and sex to be used without quoting ddply(dfx, .(group, sex), summarize, mean = round(mean(age), 2), sd = round(sd(age), 2)) # An example using a formula for .variables ddply(baseball[1:100,], ~ year, nrow) # Applying two functions; nrow and ncol ddply(baseball, .(lg), c("nrow", "ncol")) # Calculate mean runs batted in for each year rbi <- ddply(baseball, .(year), summarise, mean_rbi = mean(rbi, na.rm = TRUE)) # Plot a line chart of the result plot(mean_rbi ~ year, type = "l", data = rbi) # make new variable career_year based on the # start year for each player (id) base2 <- ddply(baseball, .(id), mutate, career_year = year - min(year) + 1 ) } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ \code{\link{tapply}} for similar functionality in the base package Other data frame input: \code{\link{d_ply}}, \code{\link{daply}}, \code{\link{dlply}} Other data frame output: \code{\link{adply}}, \code{\link{ldply}}, \code{\link{mdply}} } \keyword{manip} plyr/man/daply.Rd0000644000176000001440000000540712057740032013451 0ustar ripleyusers\name{daply} \alias{daply} \title{Split data frame, apply function, and return results in an array.} \usage{ daply(.data, .variables, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop_i = TRUE, .drop_o = TRUE, .parallel = FALSE, .paropts = NULL) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{data frame to be processed} \item{.variables}{variables to split data frame by, as quoted variables, a formula or character vector} \item{.drop_i}{should combinations of variables that do not appear in the input data be preserved (FALSE) or dropped (TRUE, default)} \item{.drop_o}{should extra dimensions of length 1 in the output be dropped, simplifying the output. Defaults to \code{TRUE}} } \value{ if results are atomic with same type and dimensionality, a vector, matrix or array; otherwise, a list-array (a list with dimensions) } \description{ For each subset of data frame, apply function then combine results into an array. \code{daply} with a function that operates column-wise is similar to \code{\link{aggregate}}. } \section{Input}{ This function splits data frames by variables. } \section{Output}{ If there are no results, then this function will return a vector of length 0 (\code{vector()}). } \examples{ daply(baseball, .(year), nrow) # Several different ways of summarising by variables that should not be # included in the summary daply(baseball[, c(2, 6:9)], .(year), colwise(mean)) daply(baseball[, 6:9], .(baseball$year), colwise(mean)) daply(baseball, .(year), function(df) colwise(mean)(df[, 6:9])) } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ Other array output: \code{\link{aaply}}, \code{\link{laply}}, \code{\link{maply}} Other data frame input: \code{\link{d_ply}}, \code{\link{ddply}}, \code{\link{dlply}} } \keyword{manip} plyr/man/d_ply.Rd0000644000176000001440000000432312057740032013443 0ustar ripleyusers\name{d_ply} \alias{d_ply} \title{Split data frame, apply function, and discard results.} \usage{ d_ply(.data, .variables, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop = TRUE, .print = FALSE, .parallel = FALSE, .paropts = NULL) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{data frame to be processed} \item{.variables}{variables to split data frame by, as \code{\link{as.quoted}} variables, a formula or character vector} \item{.drop}{should combinations of variables that do not appear in the input data be preserved (FALSE) or dropped (TRUE, default)} \item{.print}{automatically print each result? (default: \code{FALSE})} } \value{ Nothing } \description{ For each subset of a data frame, apply function and discard results } \section{Input}{ This function splits data frames by variables. } \section{Output}{ All output is discarded. This is useful for functions that you are calling purely for their side effects like displaying plots or saving output. } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ Other data frame input: \code{\link{daply}}, \code{\link{ddply}}, \code{\link{dlply}} Other no output: \code{\link{a_ply}}, \code{\link{l_ply}}, \code{\link{m_ply}} } \keyword{manip} plyr/man/create_progress_bar.Rd0000644000176000001440000000343712057740032016354 0ustar ripleyusers\name{create_progress_bar} \alias{create_progress_bar} \title{Create progress bar.} \usage{ create_progress_bar(name = "none", ...) } \arguments{ \item{name}{type of progress bar to create} \item{...}{other arguments passed onto progress bar function} } \description{ Create progress bar object from text string. } \details{ Progress bars give feedback on how apply step is proceeding. This is mainly useful for long running functions, as for short functions, the time taken up by splitting and combining may be on the same order (or longer) as the apply step. Additionally, for short functions, the time needed to update the progress bar can significantly slow down the process. For the trivial examples below, using the tk progress bar slows things down by a factor of a thousand. Note the that progress bar is approximate, and if the time taken by individual function applications is highly non-uniform it may not be very informative of the time left. There are currently four types of progress bar: "none", "text", "tk", and "win". See the individual documentation for more details. In plyr functions, these can either be specified by name, or you can create the progress bar object yourself if you want more control over its apperance. See the examples. } \examples{ # No progress bar l_ply(1:100, identity, .progress = "none") \dontrun{ # Use the Tcl/Tk interface l_ply(1:100, identity, .progress = "tk") } # Text-based progress (|======|) l_ply(1:100, identity, .progress = "text") # Choose a progress character, run a length of time you can see l_ply(1:10000, identity, .progress = progress_text(char = ".")) } \seealso{ \code{\link{progress_none}}, \code{\link{progress_text}}, \code{\link{progress_tk}}, \code{\link{progress_win}} } \keyword{utilities} plyr/man/count.Rd0000644000176000001440000000313212057740032013461 0ustar ripleyusers\name{count} \alias{count} \title{Count the number of occurences.} \usage{ count(df, vars = NULL, wt_var = NULL) } \arguments{ \item{df}{data frame to be processed} \item{vars}{variables to count unique values of} \item{wt_var}{optional variable to weight by - if this is non-NULL, count will sum up the value of this variable for each combination of id variables.} } \value{ a data frame with label and freq columns } \description{ Equivalent to \code{as.data.frame(table(x))}, but does not include combinations with zero counts. } \details{ Speed-wise count is competitive with \code{\link{table}} for single variables, but it really comes into its own when summarising multiple dimensions because it only counts combinations that actually occur in the data. Compared to \code{\link{table}} + \code{\link{as.data.frame}}, \code{count} also preserves the type of the identifier variables, instead of converting them to characters/factors. } \examples{ # Count of each value of "id" in the first 100 cases count(baseball[1:100,], vars = "id") # Count of ids, weighted by their "g" loading count(baseball[1:100,], vars = "id", wt_var = "g") count(baseball, "id", "ab") count(baseball, "lg") # How many stints do players do? count(baseball, "stint") # Count of times each player appeared in each of the years they played count(baseball[1:100,], c("id", "year")) # Count of counts count(count(baseball[1:100,], c("id", "year")), "id", "freq") count(count(baseball, c("id", "year")), "freq") } \seealso{ \code{\link{table}} for related functionality in the base package } \keyword{manip} plyr/man/compact.Rd0000644000176000001440000000030512057740032013756 0ustar ripleyusers\name{compact} \alias{compact} \title{Compact list.} \usage{ compact(l) } \arguments{ \item{l}{list} } \description{ Remove all NULL entries from a list } \keyword{internal} \keyword{manip} plyr/man/colwise.Rd0000644000176000001440000000367212057740032014007 0ustar ripleyusers\name{colwise} \alias{catcolwise} \alias{colwise} \alias{numcolwise} \title{Column-wise function.} \usage{ colwise(.fun, .cols = true, ...) catcolwise(.fun, ...) numcolwise(.fun, ...) } \arguments{ \item{.fun}{function} \item{.cols}{either a function that tests columns for inclusion, or a quoted object giving which columns to process} \item{...}{other arguments passed on to \code{.fun}} } \description{ Turn a function that operates on a vector into a function that operates column-wise on a data.frame. } \details{ \code{catcolwise} and \code{numcolwise} provide version that only operate on discrete and numeric variables respectively. } \examples{ # Count number of missing values nmissing <- function(x) sum(is.na(x)) # Apply to every column in a data frame colwise(nmissing)(baseball) # This syntax looks a little different. It is shorthand for the # the following: f <- colwise(nmissing) f(baseball) # This is particularly useful in conjunction with d*ply ddply(baseball, .(year), colwise(nmissing)) # To operate only on specified columns, supply them as the second # argument. Many different forms are accepted. ddply(baseball, .(year), colwise(nmissing, .(sb, cs, so))) ddply(baseball, .(year), colwise(nmissing, c("sb", "cs", "so"))) ddply(baseball, .(year), colwise(nmissing, ~ sb + cs + so)) # Alternatively, you can specify a boolean function that determines # whether or not a column should be included ddply(baseball, .(year), colwise(nmissing, is.character)) ddply(baseball, .(year), colwise(nmissing, is.numeric)) ddply(baseball, .(year), colwise(nmissing, is.discrete)) # These last two cases are particularly common, so some shortcuts are # provided: ddply(baseball, .(year), numcolwise(nmissing)) ddply(baseball, .(year), catcolwise(nmissing)) # You can supply additional arguments to either colwise, or the function # it generates: numcolwise(mean)(baseball, na.rm = TRUE) numcolwise(mean, na.rm = TRUE)(baseball) } plyr/man/baseball.Rd0000644000176000001440000000334012057740032014077 0ustar ripleyusers\docType{data} \name{baseball} \alias{baseball} \title{Yearly batting records for all major league baseball players} \format{A 21699 x 22 data frame} \description{ This data frame contains batting statistics for a subset of players collected from \url{http://www.baseball-databank.org/}. There are a total of 21,699 records, covering 1,228 players from 1871 to 2007. Only players with more 15 seasons of play are included. } \section{Variables}{ Variables: \itemize{ \item id, unique player id \item year, year of data \item stint \item team, team played for \item lg, league \item g, number of games \item ab, number of times at bat \item r, number of runs \item h, hits, times reached base because of a batted, fair ball without error by the defense \item X2b, hits on which the batter reached second base safely \item X3b, hits on which the batter reached third base safely \item hr, number of home runs \item rbi, runs batted in \item sb, stolen bases \item cs, caught stealing \item bb, base on balls (walk) \item so, strike outs \item ibb, intentional base on balls \item hbp, hits by pitch \item sh, sacrifice hits \item sf, sacrifice flies \item gidp, ground into double play } } \examples{ baberuth <- subset(baseball, id == "ruthba01") baberuth$cyear <- baberuth$year - min(baberuth$year) + 1 calculate_cyear <- function(df) { mutate(df, cyear = year - min(year), cpercent = cyear / (max(year) - min(year)) ) } baseball <- ddply(baseball, .(id), calculate_cyear) baseball <- subset(baseball, ab >= 25) model <- function(df) { lm(rbi / ab ~ cyear, data=df) } model(baberuth) models <- dlply(baseball, .(id), model) } \references{ \url{http://www.baseball-databank.org/} } \keyword{datasets} plyr/man/as.quoted.Rd0000644000176000001440000000142612057740032014240 0ustar ripleyusers\name{as.quoted} \alias{as.quoted} \title{Convert input to quoted variables.} \usage{ as.quoted(x, env = parent.frame()) } \arguments{ \item{x}{input to quote} \item{env}{environment in which unbound symbols in expression should be evaluated. Defaults to the environment in which \code{as.quoted} was executed.} } \value{ a list of quoted variables } \description{ Convert characters, formulas and calls to quoted .variables } \details{ This method is called by default on all plyr functions that take a \code{.variables} argument, so that equivalent forms can be used anywhere. Currently conversions exist for character vectors, formulas and call objects. } \examples{ as.quoted(c("a", "b", "log(d)")) as.quoted(a ~ b + log(d)) } \seealso{ \code{\link{.}} } plyr/man/as.list.split.Rd0000644000176000001440000000050012057740032015034 0ustar ripleyusers\name{as.list.split} \alias{as.list.split} \title{Convert split list to regular list.} \usage{ \method{as.list}{split} (x, ...) } \arguments{ \item{x}{object to convert to a list} \item{...}{unused} } \description{ Strip off label related attributed to make a strip list as regular list } \keyword{internal} plyr/man/as.data.frame.function.Rd0000644000176000001440000000132212057740032016560 0ustar ripleyusers\name{as.data.frame.function} \alias{as.data.frame.function} \title{Make a function return a data frame.} \usage{ \method{as.data.frame}{function} (x, row.names, optional, ...) } \arguments{ \item{x}{function to make return a data frame} \item{row.names}{necessary to match the generic, but not used} \item{optional}{necessary to match the generic, but not used} \item{...}{necessary to match the generic, but not used} } \description{ Create a new function that returns the existing function wrapped in a data.frame } \details{ This is useful when calling \code{*dply} functions with a function that returns a vector, and you want the output in rows, rather than columns } \keyword{manip} plyr/man/arrange.Rd0000644000176000001440000000206112057740032013750 0ustar ripleyusers\name{arrange} \alias{arrange} \title{Order a data frame by its colums.} \usage{ arrange(df, ...) } \arguments{ \item{df}{data frame to reorder} \item{...}{expressions evaluated in the context of \code{df} and then fed to \code{\link{order}}} } \description{ This function completes the subsetting, transforming and ordering triad with a function that works in a similar way to \code{\link{subset}} and \code{\link{transform}} but for reordering a data frame by its columns. This saves a lot of typing! } \examples{ # sort mtcars data by cylinder and displacement mtcars[with(mtcars, order(cyl, disp)), ] # Same result using arrange: no need to use with(), as the context is implicit # NOTE: plyr functions do NOT preserve row.names arrange(mtcars, cyl, disp) # Let's keep the row.names in this example myCars = cbind(vehicle=row.names(mtcars), mtcars) arrange(myCars, cyl, disp) # Sort with displacement in descending order arrange(myCars, cyl, desc(disp)) } \seealso{ \code{\link{order}} for sorting function in the base package } \keyword{manip} plyr/man/amv_dimnames.Rd0000644000176000001440000000067612057740032015003 0ustar ripleyusers\name{amv_dimnames} \alias{amv_dimnames} \title{Dimension names.} \usage{ amv_dimnames(x) } \arguments{ \item{x}{array, matrix or vector} } \description{ Consistent dimnames for vectors, matrices and arrays. } \details{ Unlike \code{\link{dimnames}} no part of the output will ever be null. If a component of dimnames is omitted, \code{amv_dimnames} will return an integer sequence of the appropriate length. } \keyword{internal} plyr/man/amv_dim.Rd0000644000176000001440000000033212057740032013744 0ustar ripleyusers\name{amv_dim} \alias{amv_dim} \title{Dimensions.} \usage{ amv_dim(x) } \arguments{ \item{x}{array, matrix or vector} } \description{ Consistent dimensions for vectors, matrices and arrays. } \keyword{internal} plyr/man/alply.Rd0000644000176000001440000000533012057740032013454 0ustar ripleyusers\name{alply} \alias{alply} \title{Split array, apply function, and return results in a list.} \usage{ alply(.data, .margins, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL, .dims = FALSE) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{matrix, array or data frame to be processed} \item{.margins}{a vector giving the subscripts to split up \code{data} by. 1 splits up by rows, 2 by columns and c(1,2) by rows and columns, and so on for higher dimensions} \item{.expand}{if \code{.data} is a data frame, should output be 1d (expand = FALSE), with an element for each row; or nd (expand = TRUE), with a dimension for each variable.} \item{.dims}{if \code{TRUE}, copy over dimensions and names from input.} } \value{ list of results } \description{ For each slice of an array, apply function then combine results into a list. } \details{ The list will have "dims" and "dimnames" corresponding to the margins given. For instance \code{alply(x, c(3,2), ...)} where \code{x} has dims \code{c(4,3,2)} will give a result with dims \code{c(2,3)}. \code{alply} is somewhat similar to \code{\link{apply}} for cases where the results are not atomic. } \section{Input}{ This function splits matrices, arrays and data frames by dimensions } \section{Output}{ If there are no results, then this function will return a list of length 0 (\code{list()}). } \examples{ alply(ozone, 3, quantile) alply(ozone, 3, function(x) table(round(x))) } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ Other array input: \code{\link{a_ply}}, \code{\link{aaply}}, \code{\link{adply}} Other list output: \code{\link{dlply}}, \code{\link{llply}}, \code{\link{mlply}} } \keyword{manip} plyr/man/adply.Rd0000644000176000001440000000517212057740032013450 0ustar ripleyusers\name{adply} \alias{adply} \title{Split array, apply function, and return results in a data frame.} \usage{ adply(.data, .margins, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{matrix, array or data frame to be processed} \item{.margins}{a vector giving the subscripts to split up \code{data} by. 1 splits up by rows, 2 by columns and c(1,2) by rows and columns, and so on for higher dimensions} \item{.expand}{if \code{.data} is a data frame, should output be 1d (expand = FALSE), with an element for each row; or nd (expand = TRUE), with a dimension for each variable.} } \value{ A data frame, as described in the output section. } \description{ For each slice of an array, apply function then combine results into a data frame. } \section{Input}{ This function splits matrices, arrays and data frames by dimensions } \section{Output}{ The most unambiguous behaviour is achieved when \code{.fun} returns a data frame - in that case pieces will be combined with \code{\link{rbind.fill}}. If \code{.fun} returns an atomic vector of fixed length, it will be \code{rbind}ed together and converted to a data frame. Any other values will result in an error. If there are no results, then this function will return a data frame with zero rows and columns (\code{data.frame()}). } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ Other array input: \code{\link{a_ply}}, \code{\link{aaply}}, \code{\link{alply}} Other data frame output: \code{\link{ddply}}, \code{\link{ldply}}, \code{\link{mdply}} } \keyword{manip} plyr/man/aaply.Rd0000644000176000001440000000642712057740032013451 0ustar ripleyusers\name{aaply} \alias{aaply} \title{Split array, apply function, and return results in an array.} \usage{ aaply(.data, .margins, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{matrix, array or data frame to be processed} \item{.margins}{a vector giving the subscripts to split up \code{data} by. 1 splits up by rows, 2 by columns and c(1,2) by rows and columns, and so on for higher dimensions} \item{.expand}{if \code{.data} is a data frame, should output be 1d (expand = FALSE), with an element for each row; or nd (expand = TRUE), with a dimension for each variable.} \item{.drop}{should extra dimensions of length 1 in the output be dropped, simplifying the output. Defaults to \code{TRUE}} } \value{ if results are atomic with same type and dimensionality, a vector, matrix or array; otherwise, a list-array (a list with dimensions) } \description{ For each slice of an array, apply function, keeping results as an array. } \details{ This function is very similar to \code{\link{apply}}, except that it will always return an array, and when the function returns >1 d data structures, those dimensions are added on to the highest dimensions, rather than the lowest dimensions. This makes \code{aaply} idempotent, so that \code{aaply(input, X, identity)} is equivalent to \code{aperm(input, X)}. } \section{Input}{ This function splits matrices, arrays and data frames by dimensions } \section{Output}{ If there are no results, then this function will return a vector of length 0 (\code{vector()}). } \examples{ dim(ozone) aaply(ozone, 1, mean) aaply(ozone, 1, mean, .drop = FALSE) aaply(ozone, 3, mean) aaply(ozone, c(1,2), mean) dim(aaply(ozone, c(1,2), mean)) dim(aaply(ozone, c(1,2), mean, .drop = FALSE)) aaply(ozone, 1, each(min, max)) aaply(ozone, 3, each(min, max)) standardise <- function(x) (x - min(x)) / (max(x) - min(x)) aaply(ozone, 3, standardise) aaply(ozone, 1:2, standardise) aaply(ozone, 1:2, diff) } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ Other array input: \code{\link{a_ply}}, \code{\link{adply}}, \code{\link{alply}} Other array output: \code{\link{daply}}, \code{\link{laply}}, \code{\link{maply}} } \keyword{manip} plyr/man/a_ply.Rd0000644000176000001440000000452212057740032013441 0ustar ripleyusers\name{a_ply} \alias{a_ply} \title{Split array, apply function, and discard results.} \usage{ a_ply(.data, .margins, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .print = FALSE, .parallel = FALSE, .paropts = NULL) } \arguments{ \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \item{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.parallel}{if \code{TRUE}, apply function in parallel, using parallel backend provided by foreach} \item{.paropts}{a list of additional options passed into the \code{\link[foreach]{foreach}} function when parallel computation is enabled. This is important if (for example) your code relies on external data or packages: use the \code{.export} and \code{.packages} arguments to supply them so that all cluster nodes have the correct environment set up for computing.} \item{.inform}{produce informative error messages? This is turned off by by default because it substantially slows processing speed, but is very useful for debugging} \item{.data}{matrix, array or data frame to be processed} \item{.margins}{a vector giving the subscripts to split up \code{data} by. 1 splits up by rows, 2 by columns and c(1,2) by rows and columns, and so on for higher dimensions} \item{.expand}{if \code{.data} is a data frame, should output be 1d (expand = FALSE), with an element for each row; or nd (expand = TRUE), with a dimension for each variable.} \item{.print}{automatically print each result? (default: \code{FALSE})} } \value{ Nothing } \description{ For each slice of an array, apply function and discard results } \section{Input}{ This function splits matrices, arrays and data frames by dimensions } \section{Output}{ All output is discarded. This is useful for functions that you are calling purely for their side effects like displaying plots or saving output. } \references{ Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data Analysis. Journal of Statistical Software, 40(1), 1-29. \url{http://www.jstatsoft.org/v40/i01/}. } \seealso{ Other array input: \code{\link{aaply}}, \code{\link{adply}}, \code{\link{alply}} Other no output: \code{\link{d_ply}}, \code{\link{l_ply}}, \code{\link{m_ply}} } \keyword{manip} plyr/inst/0000755000176000001440000000000012057740163012252 5ustar ripleyusersplyr/inst/tests/0000755000176000001440000000000012043514644013412 5ustar ripleyusersplyr/inst/tests/test-summarise.r0000644000176000001440000000065512034020705016553 0ustar ripleyuserscontext("Summarise") test_that("summarise creates correct names", { df <- summarise(mtcars, cyl, vs) expect_that(names(df), equals(c("cyl", "vs"))) df <- summarise(mtcars, x = cyl, vs) expect_that(names(df), equals(c("x", "vs"))) df <- summarise(mtcars, x = cyl, y = vs) expect_that(names(df), equals(c("x", "y"))) # df <- summarise(mtcars, mean(cyl), mean(vs)) # expect_that(names(df), equals("x", "y")) }) plyr/inst/tests/test-split-labels.r0000644000176000001440000000034112034020705017131 0ustar ripleyuserscontext("Split labels") test_that("Empty levels preserved", { df <- data.frame(fac1 = letters[1:4], fac2 = LETTERS[1:4]) a <- split_labels(df, FALSE) b <- split_labels(df[1, ], FALSE) expect_that(a, equals(b)) }) plyr/inst/tests/test-split-indices.r0000644000176000001440000000021512037542535017322 0ustar ripleyuserscontext("Split indices") test_that("Error if n too small", { expect_error(split_indices(1:10, 5), "n smaller than largest index") }) plyr/inst/tests/test-split-data-frame.r0000644000176000001440000000114512034617313017702 0ustar ripleyuserscontext("Split data frame") test_that("correct order is used", { df <- data.frame(x = factor(1:10), y = letters[1:10]) expect_that(ddply(df, .(x), .drop = FALSE), equals(df)) expect_that(ddply(df, .(x), .drop = TRUE), equals(df)) }) test_that("factor levels are preserved", { df <- data.frame(a = factor(1:4, levels = 1:5), x = runif(4)) out1 <- ddply(df, "a", strip_splits, .drop = TRUE) out2 <- ddply(df, "a", strip_splits, .drop = FALSE) expect_is(out1$a, "factor") expect_is(out2$a, "factor") expect_equal(levels(out1$a), levels(df$a)) expect_equal(levels(out2$a), levels(df$a)) }) plyr/inst/tests/test-simplify-df.r0000644000176000001440000000770212034573471017006 0ustar ripleyuserscontext("List to data frame") a <- as.POSIXct(1, origin="2011-01-01") test_that("classes preserved for atomic scalars", { li <- list(a, a+1) df <- list_to_dataframe(li) expect_that(df, is_a("data.frame")) expect_that(class(df[,1]), equals(class(a))) expect_that(nrow(df), equals(2)) expect_that(ncol(df), equals(1)) }) test_that("classes preserved for atomic scalars in list of length 1", { li <- list(a) df <- list_to_dataframe(li) expect_that(df, is_a("data.frame")) expect_that(nrow(df), equals(1)) expect_that(ncol(df), equals(1)) expect_that(class(df[,1]), equals(class(a))) }) test_that("classes preserved for atomic vectors", { li <- list(c(a, a+1), c(a+2, a+3)) df <- list_to_dataframe(li) expect_that(df, is_a("data.frame")) expect_that(nrow(df), equals(2)) expect_that(ncol(df), equals(2)) expect_that(class(df[,1]), equals(class(a))) }) test_that("classes preserved for atomic vectors in list of length 1", { li <- list(c(a, a+1)) df <- list_to_dataframe(li) expect_that(df, is_a("data.frame")) expect_that(nrow(df), equals(1)) expect_that(ncol(df), equals(2)) expect_that(class(df[,1]), equals(class(a))) }) test_that("classes preserved for data.frames", { li <- list(data.frame(V1=a, V2=a+1), data.frame(V1=a+2, V2=a+3)) df <- list_to_dataframe(li) expect_that(df, is_a("data.frame")) expect_that(nrow(df), equals(2)) expect_that(ncol(df), equals(2)) expect_that(class(df[,1]), equals(class(a))) }) test_that("names preserved for atomic scalars", { li <- list(c(foo=1), c(foo=2)) df <- list_to_dataframe(li) expect_that(df, is_a("data.frame")) expect_that(nrow(df), equals(2)) expect_that(ncol(df), equals(1)) expect_that(names(df), equals(c("foo"))) }) test_that("names preserved for atomic scalars in list of length 1", { li <- list(c(foo=1)) df <- list_to_dataframe(li) expect_that(df, is_a("data.frame")) expect_that(nrow(df), equals(1)) expect_that(ncol(df), equals(1)) expect_that(names(df), equals(c("foo"))) }) test_that("names preserved for atomic vectors", { li <- list(c(foo=1, bar=2), c(foo=3, bar=4)) df <- list_to_dataframe(li) expect_that(df, is_a("data.frame")) expect_that(nrow(df), equals(2)) expect_that(ncol(df), equals(2)) expect_that(class(df), equals("data.frame")) expect_that(names(df), equals(c("foo","bar"))) }) test_that("names preserved for atomic vectors n list of length 1", { li <- list(c(foo=1, bar=2)) df <- list_to_dataframe(li) expect_that(df, is_a("data.frame")) expect_that(nrow(df), equals(1)) expect_that(ncol(df), equals(2)) expect_that(names(df), equals(c("foo","bar"))) }) test_that("names preserved for data.frames", { li <- list(data.frame(foo=1, bar=2), data.frame(foo=3, bar=4)) df <- list_to_dataframe(li) expect_that(df, is_a("data.frame")) expect_that(nrow(df), equals(2)) expect_that(ncol(df), equals(2)) expect_that(names(df), equals(c("foo","bar"))) }) test_that("names preserved and filled for atomic vectors", { li <- list(c(foo=1, 2), c(foo=3, 4)) df <- list_to_dataframe(li) expect_that(df, is_a("data.frame")) expect_that(nrow(df), equals(2)) expect_that(ncol(df), equals(2)) expect_that(names(df), equals(c("foo","V1"))) }) test_that("names captured from list", { li <- list(a = 1:5, b = 5:10, c = 5:15) df <- ldply(li, function(x) mean(x)) expect_that(df$.id, equals(c("a", "b", "c"))) df <- ldply(li, function(x) { if (any(x >= 10)) mean(x) }) expect_that(df$.id, equals(c("b", "c"))) }) test_that("correct number of rows outputted", { testdata <- data.frame(a = rep(letters[1:3], each = 5), b = rnorm(15)) res <- ddply(testdata, .(a), function(x) c(mean(x$b), sd(x$b))) expect_that(nrow(res), equals(3)) }) test_that("matrices converted to data frames", { mat <- matrix(1:20, ncol = 4) colnames(mat) <- letters[1:4] li <- list(a = mat, b = mat) df <- list_to_dataframe(li) expect_equal(nrow(df), 2 * nrow(mat)) expect_equal(names(df), c(".id", "a", "b", "c", "d")) }) plyr/inst/tests/test-revalue.r0000644000176000001440000001070212035565262016220 0ustar ripleyuserscontext("Replace values") # Character vector chr <- c("A2", "A1", "A3", "A1") # Factor: To complicate things, set levels in a different order fac <- factor(c("A1", "A2", "A3"), levels=c("A2", "A1", "A3")) # Numeric vector num <- c(4, 1, 5, 8) # test warn if any missing test_that("Empty mapping results in no change", { expect_identical(mapvalues(chr, from = NULL, to = NULL), chr) expect_identical(revalue(chr, NULL), chr) expect_identical(mapvalues(fac, from = NULL, to = NULL), fac) expect_identical(revalue(fac, NULL), fac) }) test_that("Basic mapping works", { newchr <- c("B2", "A1", "B3", "A1") expect_identical(mapvalues(chr, c("A3", "A2"), c("B3", "B2")), newchr) expect_identical(revalue(chr, c(A3="B3", A2="B2")), newchr) newfac <- factor(c("A1", "B2", "B3"), levels=c("B2", "A1", "B3")) expect_identical(mapvalues(fac, c("A3", "A2"), c("B3", "B2")), newfac) expect_identical(revalue(fac, c(A3="B3", A2="B2")), newfac) newnum <- c(40, 1, 5, 80) expect_identical(mapvalues(num, c(4, 8), c(40, 80)), newnum) # revalue doesn't work for numeric vectors }) test_that("Mapping with repeated original values works - should use first instance, and give message", { newchr <- c("A2", "B1", "A3", "B1") expect_message( expect_identical(mapvalues(chr, c("A1", "A1"), c("B1", "C1")), newchr)) expect_message( expect_identical(revalue(chr, c(A1="B1", A1="C1")), newchr)) newfac <- factor(c("B1", "A2", "A3"), levels=c("A2", "B1", "A3")) expect_message( expect_identical(mapvalues(fac, c("A1", "A1"), c("B1", "C1")), newfac)) expect_message( expect_identical(revalue(fac, c(A1="B1", A1="C1")), newfac)) newnum <- c(4, 1, 5, 80) expect_message( expect_identical(mapvalues(num, c(8, 8), c(80, 800)), newnum)) }) test_that("Mapping with repeated new value works (for factors, levels should be in earliest position)", { newchr <- c("BX", "A1", "BX", "A1") expect_identical(mapvalues(chr, c("A3", "A2"), c("BX", "BX")), newchr) expect_identical(revalue(chr, c(A3="BX", A2="BX")), newchr) newfac <- factor(c("A1", "BX", "BX"), levels=c("BX", "A1")) expect_identical(revalue(fac, c(A3="BX", A2="BX")), newfac) # Factors can have levels in different orders newfac2 <- factor(c("BX", "A2", "BX"), levels=c("A2", "BX")) expect_identical(revalue(fac, c(A3="BX", A1="BX")), newfac2) }) test_that("Mapping with multiple matches works", { newchr <- c("B2", "B1", "A3", "B1") expect_identical(mapvalues(chr, c("A1", "A2"), c("B1", "B2")), newchr) expect_identical(revalue(chr, c(A1="B1", A2="B2")), newchr) # Not relevant for factors because they can't have two levels be the same }) test_that("Mapping with non-matching original levels results in no change, and message", { expect_message( expect_identical(revalue(chr, c(A4="B4")), chr)) expect_message( expect_identical(revalue(chr, c(A3="B3", A4="B4")), c("A2", "A1", "B3", "A1"))) expect_message( expect_identical(revalue(fac, c(A4="B4")), fac)) expect_message( expect_identical(revalue(fac, c(A3="B3", A4="B4")), factor(c("A1", "A2", "B3"), levels=c("A2", "A1", "B3")))) }) test_that("Swapping values works", { newchr <- c("A3", "A1", "A2", "A1") expect_identical(mapvalues(chr, c("A2", "A3"), c("A3", "A2")), newchr) expect_identical(revalue(chr, c(A2="A3", A3="A2")), newchr) newfac <- factor(c("A1", "A3", "A2"), levels=c("A3", "A1", "A2")) expect_identical(mapvalues(fac, c("A2", "A3"), c("A3", "A2")), newfac) expect_identical(revalue(fac, c(A2="A3", A3="A2")), newfac) }) test_that("Mapping with ' ' and '$' in original and replacement works", { chr2 <- c("A2", "A $1", "A3", "A $1") expect_identical(revalue(chr2, c("A $1"="B $1")), c("A2", "B $1", "A3", "B $1")) fac2 <- factor(c("A $1", "A2", "A3"), levels=c("A2", "A $1", "A3")) expect_identical(revalue(fac2, c("A $1"="B $1")), factor(c("B $1", "A2", "A3"), levels=c("A2", "B $1", "A3"))) }) test_that("revalue and mapvalues only accept atomic vectors", { expect_error(revalue(list(A=3), c("3"=30))) expect_error(mapvalues(list(A=3), 3, 30)) }) test_that("revalue and mapvalues accept empty vectors and NULL", { expect_identical(revalue(character(0), c("3"=30), warn_missing=FALSE), character(0)) expect_identical(mapvalues(character(0), 3, 30, warn_missing=FALSE), character(0)) expect_identical(revalue(NULL, c("3"=30), warn_missing=FALSE), NULL) expect_identical(mapvalues(NULL, 3, 30, warn_missing=FALSE), NULL) }) plyr/inst/tests/test-replicate.r0000644000176000001440000000025212034020705016507 0ustar ripleyuserscontext("Replicate") test_that("length of results are correct", { a <- rlply(4, NULL) b <- rlply(4, 1) expect_equal(length(a), 4) expect_equal(length(b), 4) }) plyr/inst/tests/test-rename.r0000644000176000001440000000210412035565262016021 0ustar ripleyuserscontext("Rename") test_that("No match leaves names unchanged", { x <- c(a = 1, b = 2, c = 3, 4) y <- rename(x, c(d = "e"), warn_missing = FALSE) expect_equal(names(x), names(y)) }) test_that("Missing old values result in message", { # This is the same rename operation as above, but should give a message x <- c(a = 1, b = 2, c = 3, 4) expect_message(rename(x, c(d = "e"))) }) test_that("Single name match makes change", { x <- c(a = 1, b = 2) y <- rename(x, c(b = "c")) expect_equal(names(y), c("a", "c")) }) test_that("Multiple names correctly changed", { x <- c(a = 1, b = 2, c = 3) y <- rename(x, c("c" = "f", "b" = "e", "a" = "d")) expect_equal(names(y), c("d", "e", "f")) }) test_that("Empty vectors and lists", { expect_identical(rename(character(), c("c" = "f"), warn_missing = FALSE), character()) expect_identical(rename(list(), c("c" = "f"), warn_missing = FALSE), list()) }) test_that("Renaming lists", { x <- list(a = 1, b = 2, c = 3) y <- rename(x, c("c" = "f", "b" = "e", "a" = "d")) expect_identical(y, list(d = 1, e = 2, f = 3)) }) plyr/inst/tests/test-rbind.r0000644000176000001440000001047012034313176015647 0ustar ripleyuserscontext("rbind.fill") test_that("variable classes are preserved", { a <- data.frame(a = factor(letters[1:3]), b = 1:3, c = date()) b <- data.frame( a = factor(letters[3:5]), d = as.Date(c("2008-01-01", "2009-01-01", "2010-01-01"))) b$e <- as.POSIXlt(as.Date(c("2008-01-01", "2009-01-01", "2010-01-01"))) b$f <- matrix (1:6, nrow = 3) ab1 <- rbind.fill(a, b)[, letters[1:6]] ab2 <- rbind.fill(b, a)[c(4:6, 1:3), letters[1:6]] ab2$a <- factor(ab2$a, levels(ab1$a)) rownames(ab2) <- NULL expect_that(ab1, equals(ab2)) expect_that(unname(lapply(ab1, class)), equals(list("factor", "integer", "factor", "Date", c("POSIXct", "POSIXt"), "matrix"))) }) test_that("same as rbind for simple cases", { bsmall <- baseball[1:1000, ] bplayer <- split(bsmall, bsmall$id) b1 <- do.call("rbind", bplayer) rownames(b1) <- NULL b2 <- rbind.fill(bplayer) expect_that(b1, equals(b2)) }) test_that("columns are in expected order", { a <- data.frame(a = 1, b = 2, c = 3) b <- data.frame(b = 2, d = 4, e = 4) c <- data.frame(c = 1, b = 2, a = 1) expect_that(names(rbind.fill(a, b)), equals(c("a", "b", "c", "d", "e"))) expect_that(names(rbind.fill(a, c)), equals(c("a", "b", "c"))) expect_that(names(rbind.fill(c, a)), equals(c("c", "b", "a"))) }) test_that("matrices are preserved", { a <- data.frame(a = factor(letters[3:5])) a$b <- matrix(1:6, nrow = 3) expect_that(rbind.fill(a, a)$b, is_equivalent_to(rbind(a, a)$b)) b <- data.frame(c = 1:3) ab1 <- rbind.fill(a, b) [ , letters[1:3]] ab2 <- rbind.fill(b, a) [c(4:6, 1:3), letters[1:3]] ab2$a <- factor(ab2$a, levels(ab1$a)) rownames(ab2) <- NULL expect_that(ab1, equals(ab2)) }) test_that("missing levels in factors preserved", { f <- addNA(factor(c("a", "b", NA))) df1 <- data.frame(a = f) df2 <- data.frame(b = f) rbind.fill(df1, df2) }) test_that("time zones are preserved", { dstart <- "2011-01-01 00:01" dstop <- "2011-01-02 04:15" get_tz <- function(x) attr(as.POSIXlt(x), "tz") tzs <- c("", "CET", "UTC") for(tz in tzs) { start <- data.frame(x = as.POSIXct(dstart, tz = tz)) end <- data.frame(x = as.POSIXct(dstop, tz = tz)) both <- rbind.fill(start, end) expect_that(get_tz(both$x)[1], equals(tz), label = tz) } }) test_that("arrays are ok", { df <- data.frame(x = 1) df$x <- array(1, 1) df2 <- rbind.fill(df, df) expect_that(df2$x, is_equivalent_to(rbind(df, df)$x)) }) test_that("attributes are preserved", { d1 <- data.frame(a = runif(10), b = runif(10)) d2 <- data.frame(a = runif(10), b = runif(10)) attr(d1$b, "foo") <- "one" attr(d1$b, "bar") <- "bar" attr(d2$b, "foo") <- "two" attr(d2$b, "baz") <- "baz" d12 <- rbind.fill(d1, d2) d21 <- rbind.fill(d2, d1) expect_that(attr(d12$b, "foo"), equals("one")) expect_that(attr(d21$b, "foo"), equals("two")) }) test_that("characters override factors", { d1a <- data.frame(x=c('a','b'), y=1:2) d2a <- data.frame(x=c('b','d'), z=1:2, stringsAsFactors=F) d1b <- data.frame(x=c('a','b'), y=1:2, stringsAsFactors=F) d2b <- data.frame(x=c('b','d'), z=1:2) d3a <- rbind.fill(d1a,d2a) d3b <- rbind.fill(d1b,d2b) expect_that(d3a$x, is_a("character")) expect_that(d3b$x, is_a("character")) }) test_that("zero row data frames ok", { d1 <- data.frame(x = 1:2, y = 2:3) d2 <- data.frame(y = 3:4, z = 5:6) za <- rbind.fill(subset(d1, FALSE)) zb <- rbind.fill(d1, subset(d2, FALSE)) zc <- rbind.fill(subset(d1, FALSE), subset(d2, FALSE)) expect_equal(class(za), "data.frame") expect_equal(nrow(za), 0) expect_true(all(names(za) %in% c("x", "y"))) expect_equal(class(zb), "data.frame") expect_equal(nrow(zb), 2) expect_true(all(names(zb) %in% c("x", "y", "z"))) expect_equal(zb$y, d1$y) expect_equal(zb$z, rep(as.numeric(NA), nrow(d1))) expect_equal(class(zc), "data.frame") expect_equal(nrow(zc), 0) expect_true(all(names(zc) %in% c("x", "y", "z"))) }) test_that("zero col data frames ok", { d1 <- data.frame(x = "a", y = 1L) d2 <- data.frame(y = 2L, z = 3L) za <- rbind.fill(d1[0, ], d2[0, ]) zb <- rbind.fill(d1[0, ], d2) zc <- rbind.fill(d1, d2[0, ]) expect_equal(names(za), c("x", "y", "z")) expect_equal(names(zb), c("x", "y", "z")) expect_equal(names(zc), c("x", "y", "z")) expect_equal(nrow(za), 0) expect_equal(nrow(zb), 1) expect_equal(nrow(zc), 1) }) plyr/inst/tests/test-rbind.matrix.r0000755000176000001440000000740112034310165017150 0ustar ripleyuserscontext("rbind.fill.matrix") test_that ("merge 3 matrices: should behave like rbind.fill for data.frame",{ a <- matrix (1:9, 3) b <- matrix (1:12, 3) c <- matrix (1:12, 2) new <- rbind.fill.matrix(a, b, c) ref <- as.matrix (rbind.fill (as.data.frame (a), as.data.frame (b), as.data.frame (c))) colnames (ref) <- seq_len(ncol(ref)) # rbind.fill.matrix always sets # colnames. I don't think it's worth # wile trying to suppress that if no # matrix had column names before rownames (ref) <- NULL expect_that(new, equals(ref)) }) test_that ("additional columns are NA: should behave like rbind.fill for data.frame",{ a <- matrix (1:9, 3) b <- matrix (1:12, 3) new <- rbind.fill.matrix (a, b) ref <- as.matrix (rbind.fill (as.data.frame (a), as.data.frame (b))) colnames (ref) <- seq_len(ncol(ref)) rownames (ref) <- NULL expect_that(new, equals(ref)) }) test_that ("merge with column names: should behave like rbind.fill for data.frame",{ a <- matrix (1:9, 3) colnames (a) <- letters [1 : 3] b <- matrix (1:9, 3) colnames (b) <- letters [3 : 1] new <- rbind.fill.matrix (a, b) ref <- as.matrix (rbind.fill (as.data.frame (a), as.data.frame (b))) rownames (ref) <- NULL expect_that(new, equals(ref)) }) test_that ("merge with column names: should behave like rbind.fill for data.frame",{ a <- matrix (1:9, 3) colnames (a) <- letters [1 : 3] b <- matrix (1:9, 3) colnames (b) <- letters [c (1, 2, 4)] new <- rbind.fill.matrix (a, b) ref <- as.matrix (rbind.fill (as.data.frame (a), as.data.frame (b))) rownames (ref) <- NULL expect_that(new, equals(ref)) }) test_that ("only 1 element: should behave like rbind.fill for data.frame",{ a <- matrix (1, 1) colnames (a) <- letters [2] b <- matrix (1:9, 3) colnames (b) <- letters [c (1, 2, 4)] new <- rbind.fill.matrix (a, b) ref <- as.matrix (rbind.fill (as.data.frame (a), as.data.frame (b))) rownames (ref) <- NULL expect_that(new, equals(ref)) }) test_that ("character + numeric: should behave like rbind.fill for data.frame",{ a <- matrix (letters [1:9], 3) colnames (a) <- letters [1:3] b <- matrix (1:9, 3) colnames (b) <- letters [c (1, 2, 4)] new <- rbind.fill.matrix (a, b) ref <- rbind.fill (as.data.frame (a, stringsAsFactors = FALSE), as.data.frame (b, stringsAsFactors = FALSE)) ref <- as.matrix (sapply (ref, as.character)) # the last column is integer and would gain a second # character with direct as.matrix expect_that(new, equals(ref)) }) test_that ("factor: stops with error",{ a <- factor (rep (LETTERS [1 : 3], 3)) dim (a) <- c (3, 3) expect_that(rbind.fill.matrix (a), throws_error ("factor")) }) test_that ("vector: uses as.matrix",{ a <- 1 new <- rbind.fill.matrix (a) ref <- data.frame (a = I (as.matrix (a))) colnames (ref) <- paste ("X", seq_len (ncol (ref)), sep = "") expect_that(new, equals (new)) }) test_that("zero-row matrices", { m1 <- matrix(nrow=0, ncol=2, dimnames=list(NULL, c("x", "y"))) m2 <- matrix(nrow=0, ncol=2, dimnames=list(NULL, c("y", "z"))) m3 <- matrix(c(1,2), nrow=2, ncol=1, dimnames=list(NULL, "y")) ba <- rbind.fill.matrix(m1) bb <- rbind.fill.matrix(m2, m3) bc <- rbind.fill.matrix(m1, m2) expect_equal(class(ba), "matrix") expect_equal(nrow(ba), 0) expect_true(all(colnames(ba) %in% c("x", "y"))) expect_equal(class(bb), "matrix") expect_equal(nrow(bb), 2) expect_true(all(names(bb) %in% c("x", "y", "z"))) expect_equal(bb[,"y"], m3[,"y"]) expect_equal(bb[,"z"], rep(as.numeric(NA), nrow(m3))) expect_equal(class(bc), "matrix") expect_equal(nrow(bc), 0) expect_true(all(colnames(bc) %in% c("x", "y", "z"))) }) plyr/inst/tests/test-quote.r0000644000176000001440000000136312034020705015700 0ustar ripleyuserscontext("Quoting") test_that("quoting captures current environment", { x <- .(a, b, c) expect_that(attr(x, "env"), is_identical_to(environment())) x <- as.quoted(c("a", "b", "c")) expect_that(attr(x, "env"), is_identical_to(environment())) }) test_that("evaluation takes place in correct environment", { a <- 2 x <- local({ a <- 1 .(a) }) expect_that(eval.quoted(x)$a, equals(1)) df <- data.frame(x = 1:10) x <- local({ a <- 1 .(x * a) }) expect_that(eval.quoted(x, df)[[1]], equals(1:10)) }) test_that("names work for long expressions", { q <- .(foo = barjasdfgjadhfgjsdhfgusdhfgusheguisdhguioahsrofasdgsdfgsdfg + dfgafgasdfgsdfgsdfgsdfgsdfgsdfgsdfg) expect_that(names(q), equals("foo")) }) plyr/inst/tests/test-progress.r0000644000176000001440000000037512034020705016411 0ustar ripleyuserscontext("Progress bars") test_that("unknown progress bar raised warning, not error", { old <- options(warn = 2) on.exit(options(old)) expect_that( llply(1:10, identity, .progress = "blah"), throws_error("Cannot find progress bar") ) }) plyr/inst/tests/test-parallel.r0000644000176000001440000000135712055503561016353 0ustar ripleyuserscontext("Parallel") if (require("doMC", quietly = TRUE)) { registerDoMC(2) test_that("l_ply respects .parallel", { expect_that( l_ply(c(0.1, 0.1), Sys.sleep, .parallel = TRUE), takes_less_than(0.15)) }) test_that("l_ply + .parallel complains about invalid arguments", { expect_message( l_ply(1:10, force, .parallel = TRUE, .print = TRUE), "Printing disabled") expect_message( l_ply(1:10, force, .parallel = TRUE, .progress = "text"), "Progress disabled") }) test_that(".paropts passes options to foreach", { combine <- function(a, b) NULL x <- llply(1:10, identity, .parallel = TRUE, .paropts = list(.combine = combine)) expect_equal(x, NULL) }) registerDoMC(1) } plyr/inst/tests/test-ninteraction.r0000644000176000001440000000325312057432532017252 0ustar ripleyuserscontext("id") simple_vectors <- list( letters, sample(letters), 1:26 ) test_that("for vector, equivalent to rank", { for(case in simple_vectors) { rank <- rank(case, ties = "min") rank_df <- id(as.data.frame(case)) expect_that(rank, is_equivalent_to(rank_df)) } }) test_that("duplicates numbered sequentially", { for(case in simple_vectors) { rank <- rep(rank(case, ties = "min"), each = 2) rank_df <- id(as.data.frame(rep(case, each = 2))) expect_that(rank, is_equivalent_to(rank_df)) } }) test_that("n calculated correctly", { n <- function(x) attr(id(x), "n") for(case in simple_vectors) { expect_that(n(as.data.frame(case)), equals(26)) } }) test_that("for vector + constant, equivalent to rank", { for(case in simple_vectors) { rank <- rank(case, ties = "min") after <- id(data.frame(case, x = 1)) before <- id(data.frame(x = 1, case)) expect_that(rank, is_equivalent_to(before)) expect_that(rank, is_equivalent_to(after)) } }) test_that("grids are correctly ranked", { df <- rev(expand.grid(1:10, 1:2)) expect_that(id(df), is_equivalent_to(1:20)) expect_that(id(df, drop = T), is_equivalent_to(1:20)) }) test_that("NAs are placed last", { expect_that(id_var(c(NA, 1)), is_equivalent_to(c(2, 1))) }) test_that("zero length input gives single number", { expect_that(id(character()), is_equivalent_to(integer())) }) test_that("zero column data frame gives seq_len(nrow)", { df <- as.data.frame(matrix(nrow = 10, ncol = 0)) expect_equivalent(id(df), 1:10) }) test_that("empty list doesn't affect n", { out <- id(list(integer(), 1:5)) expect_equivalent(out, 1:5) expect_equal(attr(out, "n"), 5) }) plyr/inst/tests/test-mutate.r0000644000176000001440000000105512034020705016040 0ustar ripleyuserscontext("Mutate") test_that("mutate behaves the same as transform", { m1 <- mutate(airquality, Ozone = -Ozone) t1 <- mutate(airquality, Ozone = -Ozone) expect_that(m1, equals(t1)) m2 <- mutate(airquality, new = -Ozone, Temp = (Temp-32)/1.8) t2 <- mutate(airquality, new = -Ozone, Temp = (Temp-32)/1.8) expect_that(m2, equals(t2)) }) test_that("columns can depend on previously created", { m1 <- mutate(airquality, dm = Month + Day / 31, dm2 = 2 * dm) dm2 <- with(airquality, 2 * (Month + Day / 31)) expect_that(m1$dm2, equals(dm2)) }) plyr/inst/tests/test-mapply.r0000644000176000001440000000160312034020705016042 0ustar ripleyuserscontext("Mapply") test_that("Lack of names is preserved", { list <- mlply(cbind(1:5, 1:5), list) expect_that(names(list[[1]]), equals(NULL)) vector <- mlply(cbind(1:5, 1:5), c) expect_that(names(vector[[1]]), equals(NULL)) }) test_that("No expansion creates single output dimension", { a <- maply(cbind(1:20, 1:20), "+", .expand = FALSE) expect_that(a, is_equivalent_to(1:20 * 2)) d <- mdply(cbind(1:20, 1:20), "+", .expand = FALSE) expect_that(d$X1, equals(1:20)) expect_that(d$V1, equals(1:20 * 2)) }) test_that("Expand = TRUE creates multiple output dimensions", { a <- maply(cbind(1:20, 1:20), "+", .expand = TRUE) expect_that(dim(a), equals(c(20, 20))) expect_that(diag(a), is_equivalent_to(1:20 * 2)) d <- mdply(cbind(1:20, 1:20), "+", .expand = TRUE) expect_that(d$X1, equals(1:20)) expect_that(d$X2, equals(1:20)) expect_that(d$V1, equals(1:20 * 2)) }) plyr/inst/tests/test-list.r0000644000176000001440000000112612034020705015513 0ustar ripleyuserscontext("Lists") test_that("data frame variables converted to list names", { x <- dlply(esoph, .(alcgp), function(df) mean(df$ncases)) expect_that(names(x), equals(levels(esoph$alcgp))) x <- dlply(esoph, .(alcgp, agegp), function(df) mean(df$ncases)) y <- ddply(esoph, .(alcgp, agegp), function(df) mean(df$ncases)) labs <- paste(y$alcgp, y$agegp, sep = ".") expect_that(names(x), equals(labs)) }) test_that("list names are preserved", { a <- 1:10 expect_that(names(llply(a)), equals(NULL)) names(a) <- letters[1:10] expect_that(names(llply(a)), equals(letters[1:10])) }) plyr/inst/tests/test-join.r0000644000176000001440000001212512034321372015504 0ustar ripleyuserscontext("Join") # Create smaller subset of baseball data (for speed) bsmall <- subset(baseball, id %in% sample(unique(baseball$id), 20))[, 1:5] bsmall$id <- factor(bsmall$id) bsmall <- bsmall[sample(rownames(bsmall)), ] rownames(bsmall) <- NULL first <- ddply(bsmall, "id", summarise, first = min(year)) test_that("results consistent with merge", { b2 <- merge(bsmall, first, by = "id", all.x = TRUE) b3 <- join(bsmall, first, by = "id") b4 <- join(first, bsmall, by = "id")[names(b3)] b2 <- arrange(b2, id, year, stint) b3 <- arrange(b3, id, year, stint) b4 <- arrange(b4, id, year, stint) expect_that(b2, equals(b3)) expect_that(b2, equals(b4)) }) test_that("order is preserved", { b3 <- join(bsmall, first, by = "id") expect_that(bsmall$id, equals(b3$id)) expect_that(bsmall$year, equals(b3$year)) expect_that(bsmall$stint, equals(b3$stint)) }) test_that("rownames are preserved", { b3 <- join(bsmall, first, by = "id") expect_that(rownames(b3), equals(rownames(bsmall))) }) test_that("duplicated keys are duplicated", { x <- data.frame(a = c("a", "b"), b = c("a", "b")) y <- data.frame(a = c("a", "a"), z = c(1, 2)) left <- join(x, y, by = "a") expect_that(nrow(left), equals(3)) expect_that(left$z, equals(c(1, 2, NA))) inner <- join(x, y, by = "a", type = "inner") expect_that(nrow(inner), equals(2)) expect_that(inner$z, equals(c(1, 2))) }) test_that("full merge preserves x and y", { a <- data.frame(x = 1:10, a = 1:10) b <- data.frame(x = 11:15, b = 1:5) ab <- join(a, b, by = "x", type = "full") expect_that(names(ab), equals(c("x", "a", "b"))) expect_that(ab$x, equals(1:15)) expect_that(ab$a, equals(c(1:10, rep(NA, 5)))) expect_that(ab$b, equals(c(rep(NA, 10), 1:5))) }) test_that("left and right are equivalent", { d1 <- data.frame(a = 1:3, b = 1:3) d2 <- data.frame(a = 1:4, c = 1:4) right <- join(d1, d2, type="right", by = "a") left <- join(d2, d1, type="left", by = "a") expect_that(left[c("a", "b" ,"c")], equals(right[c("a", "b" ,"c")])) right <- join(d1, d2, type="right", by = "a", match = "first") left <- join(d2, d1, type="left", by = "a", match = "first") expect_that(left[c("a", "b" ,"c")], equals(right[c("a", "b" ,"c")])) }) test_that("large number of columns work", { df1 <- data.frame(matrix(1:100, ncol = 50), y = 1:2) df2 <- data.frame(matrix(1:100, ncol = 50), z = 3:4) df <- join(df1, df2) expect_that(df$y, equals(1:2)) expect_that(df$z, equals(3:4)) }) test_that("many potential combinations works", { factor_n <- function(m, n) { factor(sample(n, m, rep = T), levels = seq_len(n)) } df1 <- as.data.frame(replicate(20, factor_n(100, 100))) df2 <- as.data.frame(replicate(20, factor_n(100, 100))) j <- join(df1, df2) j <- merge(df1, df2, all.x = TRUE) }) test_that("joins with no common rows work", { a <- data.frame(a = 1:10) b <- data.frame(b = 1:10) full1 <- join(a, b, type = "full") full2 <- join(a, b, type = "full", match = "first") inner1 <- join(a, b, type = "inner") inner2 <- join(a, b, type = "inner", match = "first") left1 <- join(a, b, type = "left") left2 <- join(a, b, type = "left", match = "first") right1 <- join(a, b, type = "right") right2 <- join(a, b, type = "right", match = "first") expect_equal(nrow(full1), 20) expect_equal(nrow(full2), 20) expect_equal(nrow(inner1), 0) expect_equal(nrow(inner2), 0) expect_equal(nrow(left1), 10) expect_equal(nrow(left2), 10) expect_equal(nrow(right1), 10) expect_equal(nrow(right2), 10) }) test_that("joins with zero row dataframe work", { a <- data.frame(a = integer()) b <- data.frame(a = 1:10, b = letters[1:10]) full1 <- join(a, b, type = "full") full2 <- join(a, b, type = "full", match = "first") inner1 <- join(a, b, type = "inner") inner2 <- join(a, b, type = "inner", match = "first") left1 <- join(a, b, type = "left") left2 <- join(a, b, type = "left", match = "first") right1 <- join(a, b, type = "right") right2 <- join(a, b, type = "right", match = "first") expect_equal(nrow(full1), 10) expect_equal(nrow(full2), 10) expect_equal(nrow(inner1), 0) expect_equal(nrow(inner2), 0) expect_equal(nrow(left1), 0) expect_equal(nrow(left2), 0) expect_equal(nrow(right1), 10) expect_equal(nrow(right2), 10) }) test_that("column orders are common, x only, y only", { a <- data.frame(a = 1:3, b = 1:3) b <- data.frame(a = 1:4, c = 1:4) full1 <- join(a, b, type = "full") full2 <- join(a, b, type = "full", match = "first") inner1 <- join(a, b, type = "inner") inner2 <- join(a, b, type = "inner", match = "first") left1 <- join(a, b, type = "left") left2 <- join(a, b, type = "left", match = "first") right1 <- join(a, b, type = "right") right2 <- join(a, b, type = "right", match = "first") expect_equal(names(full1), c("a", "b", "c")) expect_equal(names(full2), c("a", "b", "c")) expect_equal(names(inner1), c("a", "b", "c")) expect_equal(names(inner2), c("a", "b", "c")) expect_equal(names(left1), c("a", "b", "c")) expect_equal(names(left2), c("a", "b", "c")) expect_equal(names(right1), c("a", "b", "c")) expect_equal(names(right2), c("a", "b", "c")) }) plyr/inst/tests/test-idf.r0000644000176000001440000000421712034020705015306 0ustar ripleyuserscontext("Immutable") # Create smaller subset of baseball data (for speed) bsmall <- subset(baseball, id %in% sample(unique(baseball$id), 20))[, 1:5] bsmall$id <- factor(bsmall$id) bsmall <- bsmall[sample(rownames(bsmall)), ] rownames(bsmall) <- NULL test_that("idf is immutable", { #Since idf are constructed by scratch in both idata.frame and `[.idf]` #I will test idf objects created both ways. #create both before testing any, to make sure that subsetting #doesn't change the subsetted idf idf <- idata.frame(bsmall) x <- idf[1:10, ] y <- bsmall[1:10, ] expect_error(x[1,"year"] <- 1994) expect_error(x[["stint"]] <- rev(y[["stint"]])) expect_error(x$team <- sort(y$team)) expect_error(names(idf) <- c("ID", "YR", "ST", "TM", "LG")) expect_error(idf[1,"year"] <- 1994) expect_error(idf[["stint"]] <- rev(bsmall[["stint"]])) expect_error(idf$team <- sort(bsmall$team)) expect_error(names(idf) <- c("ID", "YR", "ST", "TM", "LG")) }) test_that("idf subset by [i]", { idf <- idata.frame(bsmall) x <- idf[3] y <- bsmall[3] expect_equal(idf[[2]], bsmall[[2]]) expect_equal(x[[1]], y[[1]]) }) test_that("idf subset data by [i,j]", { idf <- idata.frame(bsmall) x <- idf[1:10, ] y <- bsmall[1:10, ] xx <- x[3:5, c('id', 'team')] yy <- y[3:5, c('id', 'team')] xxx <- idf[ , names(idf)] yyy <- idf[ , names(y)] expect_equal(idf[3, "year"], bsmall[[3, "year"]]) expect_equal(x[, "year"], y[, "year"]) expect_equal(xx[, "id"], yy[, "id"]) expect_equal(xxx[, "team"], yyy[, "team"]) }) test_that("idf extract by [[i]]", { idf <- idata.frame(bsmall) x <- idf[6:20,] y <- bsmall[6:20,] expect_equal(x[[4]], y[[4]]) expect_equal(idf[[3]], bsmall[[3]]) expect_equal(idf[["year"]], bsmall[["year"]]) }) test_that("idf extract $name", { idf <- idata.frame(bsmall) x <- idf[500:510,] y <- bsmall[500:510,] expect_equal(x$team, y$team) expect_equal(idf$team, bsmall$team) }) test_that("idf as environment", { idf <- idata.frame(bsmall) x <- idf[5:10,] y <- bsmall[5:10,] expect_equal(with(x, mean(year)), with(y, mean(year))) expect_equal(with(idf, table(team)), with(bsmall, table(team))) }) plyr/inst/tests/test-empty.r0000644000176000001440000000245512043514644015716 0ustar ripleyuserscontext("Empty inputs") test_that("empty arrays returns object of same shape", { x <- structure(integer(0), .Dim = c(0L, 0L, 0L)) expect_that(aaply(x, 1, identity), equals(logical())) expect_that(aaply(x, 2, identity), equals(logical())) expect_that(aaply(x, 3, identity), equals(logical())) expect_that(adply(x, 1, identity), equals(data.frame())) expect_that(alply(x, 1, identity), is_equivalent_to(list())) }) test_that("empty lists return an empty object", { expect_that(llply(list(), identity), equals(list())) expect_that(laply(list(), identity), equals(logical())) expect_that(ldply(list(), identity), equals(data.frame())) }) test_that("empty data frames returns empty object", { df <- data.frame(x = numeric(0), a = numeric(0)) expect_that(ddply(df, "a", identity), equals(df)) expect_that(dlply(df, "a", identity), equals(list())) expect_that(daply(df, "a", identity), equals(logical())) }) test_that("empty data frame results returns empty object", { df <- data.frame(a = 1:10) expect_that( ddply(df, "a", function(x) NULL), equals(data.frame())) expect_that( dlply(df, "a", function(x) NULL), equals(rep(list(NULL), 10), check.attributes = FALSE)) expect_that( daply(df, "a", function(x) NULL), throws_error("must have one or more dimensions")) }) plyr/inst/tests/test-data-frame.r0000644000176000001440000000335612034020705016550 0ustar ripleyuserscontext("Data frames") test_that("results ordered in order of split variables", { d <- data.frame(x = c("a","b"), y = c("d","c"), stringsAsFactors = FALSE) plyed <- ddply(d, c("x" ,"y")) expect_that(plyed$x, equals(c("a", "b"))) expect_that(plyed$y, equals(c("d", "c"))) plyed <- ddply(d, c("y" ,"x")) expect_that(plyed$y, equals(c("c", "d"))) expect_that(plyed$x, equals(c("b", "a"))) }) test_that("character vectors not change to factors", { d <- data.frame(x = c("a","b"), y = c("d","c"), stringsAsFactors = FALSE) plyed <- ddply(d, c("x" ,"y"), nrow) expect_that(plyed$x, is_a("character")) expect_that(plyed$y, is_a("character")) plyed <- ddply(d, c("x"), identity) expect_that(plyed$x, is_a("character")) expect_that(plyed$y, is_a("character")) plyed <- ddply(d, c("x" ,"y"), nrow, .drop = FALSE) expect_that(plyed$x, is_a("character")) expect_that(plyed$y, is_a("character")) plyed <- ddply(d, c("x"), identity, .drop = FALSE) expect_that(plyed$x, is_a("character")) expect_that(plyed$y, is_a("character")) }) # Bug report contributed by Thomas P Harte test_that("column names not changed", { d1 <- data.frame(`--WEIRD`=1:5, a = letters[1:5], `-b` = 1:5, check.names = FALSE) d2 <- ddply(d1, .(`--WEIRD`), force) expect_that(names(d2), equals(names(d1))) }) # Bug reported by Karl Ove Hufthammer test_that("label variables always preserved", { d <- data.frame(x = 101:104, y = 1:4) f <- function(df) sum(df$y) g <- function(df) if(df$x <= 102) sum(df$y) out1 <- ddply(d, "x", f) # This one works correctly out2 <- ddply(d, "x", g) # This one doesn’t expect_that(names(out1), equals(names(out2))) expect_that(out1$x[1:2], equals(out2$x)) }) plyr/inst/tests/test-count.r0000644000176000001440000000215512034020705015673 0ustar ripleyuserslibrary(testthat) context("Count") count_f <- function(...) count(...)$freq table_f <- function(...) { x <- unname(as.numeric(table(rev(...)))) x[x != 0] } test_that("count matches table", { data <- list( mtcars["cyl"], mtcars["mpg"], mtcars[c("cyl", "vs")]) for(datum in data) { expect_that(count_f(datum), equals(table_f(datum))) } }) test_that("random order doesn't affect count", { usual <- count(mtcars, "cyl") for(i in 1:5) { mtcars_r <- mtcars[sample(1:nrow(mtcars)), ] expect_that(count(mtcars_r, "cyl"), equals(usual)) } }) test_that("weighted count matches xtab", { xt1 <- as.data.frame(xtabs(g ~ id, data = baseball), responseName = "freq") xt1$id <- as.character(xt1$id) ct1 <- count(baseball, "id", "g") expect_that(ct1, equals(xt1)) xt2 <- as.data.frame(xtabs(g ~ year + team, data = baseball), responseName = "freq") xt2 <- subset(xt2, freq > 0) xt2$year <- as.numeric(as.character(xt2$year)) xt2$team <- as.character(xt2$team) xt2 <- arrange(xt2, year, team) ct2 <- count(baseball, c("year", "team"), "g") expect_that(ct2, equals(xt2)) }) plyr/inst/tests/test-array.r0000644000176000001440000001425712055511503015673 0ustar ripleyuserscontext("Arrays") test_that("incorrect result dimensions raise errors", { fs <- list( function(x) rep(x, sample(10, 1)), function(x) if (x < 5) x else matrix(x, 2, 2), function(x) as.list(rep(x, sample(10, 1))), function(x) if (x < 5) list(x) else matrix(list(x), 2, 2) ) expect_that(laply(1:10, fs[[1]]), throws_error("same dim")) expect_that(laply(1:10, fs[[2]]), throws_error("same number")) expect_that(laply(1:10, fs[[3]]), throws_error("same dim")) expect_that(laply(1:10, fs[[4]]), throws_error("same number")) }) test_that("incompatible result types raise errors", { f <- function(x) if (x < 5) c(x, x) else as.list(x) expect_that(laply(1:10, f), throws_error("compatible type")) }) test_that("zero length margin operates on whole object", { a <- array(1:24, 2:4) expect_that(alply(a, NULL, sum)[[1]], equals(sum(1:24))) }) test_that("results must have positive dimensions", { expect_that( aaply(matrix(0,2,2), 2, function(x) NULL), throws_error("one or more dimensions")) }) test_that("simple operations equivalent to vectorised form", { expect_that(laply(1:10, mean), is_equivalent_to(1:10)) expect_that(laply(1:10, sqrt), is_equivalent_to(sqrt(1:10))) }) test_that("array binding is correct", { library(abind) f <- function(x) matrix(x, 2, 2) m2d <- lapply(1:10, f) m3d <- abind(m2d, along = 0) expect_that(laply(1:10, f), is_equivalent_to(m3d)) f <- function(x) array(x, c(2, 2, 2)) m3d <- lapply(1:10, f) m4d <- abind(m3d, along = 0) expect_that(laply(1:10, f), is_equivalent_to(m4d)) }) test_that("array binding of lists is correct", { #this is identical to the previous test but in list mode f <- function(x) matrix(as.list(x), 2, 2) m2d <- lapply(1:10, f) #as abind itself doesn't do lists... m3d <- aperm(array(do.call(c, m2d), c(2, 2, 10)), c(3,1,2)) expect_that(laply(1:10, f), is_equivalent_to(m3d)) f <- function(x) array(as.list(x), c(2, 2, 2)) m3d <- lapply(1:10, f) m4d <- aperm(array(do.call(c, m3d), c(2, 2, 2, 10)), c(4, 1, 2, 3)) expect_that(laply(1:10, f), is_equivalent_to(m4d)) }) # Basis of test contributed by anonymous reviewer. test_that("idempotent function equivalent to permutation", { x <- array(1:24, 4:2, dimnames = list(LETTERS[1:4], letters[24:26], letters[1:2])) perms <- unique(alply(as.matrix(subset(expand.grid(x=0:3,y=0:3,z=0:3), (x+y+z)>0 & !any(duplicated(setdiff(c(x,y,z), 0))))), 1, function(x) setdiff(x, 0))) aperms <- llply(perms, function(perm) aperm(x, unique(c(perm, 1:3)))) aaplys <- llply(perms, function(perm) aaply(x, perm, identity)) for(i in seq_along(aperms)) { perm <- paste(perms[[i]], collapse = ", ") expect_that(dim(aaplys[[i]]), equals(dim(aperms[[i]])), perm) expect_that(unname(dimnames(aaplys[[i]])), equals(dimnames(aperms[[i]])), perm) expect_that(aaplys[[i]], is_equivalent_to(aperms[[i]]), perm) } }) test_that("alply sets dims and dimnames, equivalence to permutation", { x <- array(1:24, 4:2, dimnames = list(dim1=LETTERS[1:4], dim2=letters[c(24,26,25)], dim3=NULL)) #unlisting an alply should leave elements the the same order as #an aperm with the unused dimensions shifted to the front. #check against all ways to split this array p_alply <- unique(alply(as.matrix(subset(expand.grid(x=0:3,y=0:3,z=0:3), (x+y+z)>0 & !any(duplicated(setdiff(c(x,y,z), 0))))), 1, function(x) setdiff(x, 0))) p_aperm <- llply(p_alply, function(x) union(setdiff(1:3, x), x)) alplys <- lapply(p_alply, alply, .data=x, identity, .dims = TRUE) #alply will fill in dimnames on a dim that has none, so match that here dimnames(x)[[3]] <- c("1", "2") aperms <- llply(p_aperm, .fun=aperm, a=x) m_ply(cbind(x_perm=p_alply, x_ply=alplys, x_aperm=aperms), function(x_perm, x_ply, x_aperm) { expect_equivalent(dim(x_ply), dim(x)[x_perm]) expect_equivalent(dimnames(x_ply), dimnames(x)[x_perm]) expect_equivalent(dim(x_ply), dim(x_aperm)[(length(dim(x)) - length(x_perm) + 1):(length(dim(x)))]) expect_equivalent(as.vector(unlist(x_ply)), as.vector(x_aperm)) }) }) # Test contributed by Baptiste Auguie test_that("single column data frames work when treated as an array", { foo <- function(a="a", b="b", c="c", ...){ paste(a, b, c, sep="") } df <- data.frame(b=1:2) res <- adply(df, 1, splat(foo)) expect_that(res$b, equals(1:2)) expect_that(as.character(res$V1), equals(c("a1c", "a2c"))) }) test_that("aaply equivalent to apply with correct permutation", { a <- matrix(seq_len(400), ncol = 20) expect_that(rowMeans(a), equals(aaply(a, 1, mean), check.attr = FALSE)) expect_that(colMeans(a), equals(aaply(a, 2, mean), check.attr = FALSE)) b <- structure(a, dimnames = amv_dimnames(a)) expect_that(rowMeans(b), equals(aaply(b, 1, mean), check.attr = FALSE)) expect_that(colMeans(b), equals(aaply(b, 2, mean), check.attr = FALSE)) }) test_that("array reconstruction correct with missing cells", { df <- data.frame(i = rep(1:3, each = 12), j = rep(1:3, each = 4), v = 1:36) df <- subset(df, i != j) da <- daply(df, .(i, j), function(q) sum(q$v)) dd <- ddply(df, .(i, j), summarise, v1 = sum(v)) m <- matrix(NA, 3, 3) m[cbind(dd$i, dd$j)] <- dd$v1 expect_that(da, equals(m, check.attributes = FALSE)) }) set_dimnames <- function(x, nm) { dimnames(x) <- nm x } test_that("array names do not affect output", { base <- array(1:48, dim = c(12, 4)) arrays <- list( none = base, numeric = set_dimnames(base, list(R = 1:12, C = 1:4)), numeric_rev = set_dimnames(base, list(R = 12:1, C = 4:1)), alpha = set_dimnames(base, list(R = letters[1:12], C = LETTERS[1:4])), alpha_rev = set_dimnames(base, list(R = letters[12:1], C = LETTERS[4:1])) ) for(name in names(arrays)) { array <- arrays[[name]] expect_that(aaply(array, 1, sum), equals(rowSums(array), check.attributes = FALSE), info = name) expect_that(aaply(array, 2, sum), equals(colSums(array), check.attributes = FALSE), info = name) } }) plyr/inst/tests/quickdf.r0000644000176000001440000000022612034574152015223 0ustar ripleyuserscontext("quickdf") test_that("make_names handles NAs", { x <- 1:3 names(x) <- c("", "a", NA) expect_equal(make_names(x), c("X1", "a", NA)) }) plyr/inst/CITATION0000644000176000001440000000117012034020705013372 0ustar ripleyuserscitHeader("To cite plyr in publications use:") citEntry(entry = "Article", title = "The Split-Apply-Combine Strategy for Data Analysis", author = personList(as.person("Hadley Wickham")), journal = "Journal of Statistical Software", year = "2011", volume = "40", number = "1", pages = "1--29", url = "http://www.jstatsoft.org/v40/i01/", textVersion = paste("Hadley Wickham (2011).", "The Split-Apply-Combine Strategy for Data Analysis.", "Journal of Statistical Software, 40(1), 1-29.", "URL http://www.jstatsoft.org/v40/i01/.") ) plyr/DESCRIPTION0000644000176000001440000000361712060050143012774 0ustar ripleyusersPackage: plyr Type: Package Title: Tools for splitting, applying and combining data Version: 1.8 Author: Hadley Wickham Maintainer: Hadley Wickham Description: plyr is a set of tools that solves a common set of problems: you need to break a big problem down into manageable pieces, operate on each pieces and then put all the pieces back together. For example, you might want to fit a model to each spatial location or time point in your study, summarise data by panels or collapse high-dimensional arrays to simpler summary statistics. The development of plyr has been generously supported by BD (Becton Dickinson). URL: http://had.co.nz/plyr Depends: R (>= 2.11.0) Suggests: abind, testthat (>= 0.2), tcltk, foreach, doMC, itertools, iterators License: MIT LazyData: true Collate: 'dimensions.r' 'id.r' 'indexed-array.r' 'indexed-data-frame.r' 'indexed.r' 'join.r' 'loop-apply.r' 'progress.r' 'quote.r' 'split-indices.r' 'split.r' 'utils.r' 'utils-functional.r' 'data.r' 'plyr.r' 'parallel.r' 'progress-time.r' 'a_ply.r' 'aaply.r' 'adply.r' 'alply.r' 'd_ply.r' 'daply.r' 'ddply.r' 'dlply.r' 'l_ply.r' 'laply.r' 'llply.r' 'm_ply.r' 'maply.r' 'mdply.r' 'mlply.r' 'r_ply.r' 'raply.r' 'rdply.r' 'rlply.r' 'liply.r' 'ldply.r' 'arrange.r' 'colwise.r' 'count.r' 'data-frame.r' 'defaults.r' 'each.r' 'here.r' 'match-df.r' 'mutate.r' 'name-rows.r' 'quickdf.r' 'rename.r' 'revalue.r' 'round-any.r' 'splat.r' 'strip-splits.r' 'summarise.r' 'take.r' 'try.r' 'vaggregate.r' 'idataframe.r' 'join-all.r' 'list-to-array.r' 'list-to-dataframe.r' 'list-to-vector.r' 'rbind-fill-matrix.r' 'rbind-fill.r' 'splitter-a.r' 'splitter-d.r' Packaged: 2012-12-05 21:45:23 UTC; hadley Repository: CRAN Date/Publication: 2012-12-06 08:59:31 plyr/data/0000755000176000001440000000000012057740163012206 5ustar ripleyusersplyr/data/ozone.rda0000644000176000001440000004466012034020705014026 0ustar ripleyusers7zXZi"6!XIq])TW"nRʟXVHqjnj-&c \بu`XE1L˕.*΂2ͳ NI_g\Uox5g-A<&[44?FV24MAnD܅Xe΍PLorFe>Qۜt2`qH,|P@bd"7"ZU*e#.\\a77 R^蹑@.t"mQ4Bۄ'uȌ!Q'Ү*p+TRԵ“xDfZȂK+<6CXCXe GƟyD'kLW*~13+-[ݍŷvU̧G3݂o׳sN*bJ3c]_U[B3aA*!_T7%!\pj<\0Y,"r 2$z4pYU;]Uʔ;'S";X3#Ūd?t.|VX2``)u=ϊmu׻$Ƿ֊D{yWqHiO=M;f"{cKdG0ۅD $Om 0uzQID.mzaOGFIsکaʁNGtҵt?e-i47䊲'BE+L}t :Y$'ԠX <x5}7+_\Gu6wY; Bl>H[2璼FFDҘ/V,#n<֒wz( bրTtbH%W߾T)Xbep:feB`Ƨ(#\wJU+G 13©e2}6fpSŕZ}TLiD 5Tf'״4hLdafE@! Ga]a .ĔhXfP()[nQKo&-쬍hc]Bc 9]T]-2Z1R*̙邧5.^ߑZg!VXнy6)GK%{œBuy+NSyV\:sy;jk2A2]6gj~%d S9&%0 P0QOLJ1,isjPF.Y ]_H1j~nN}fw.`wAZ Zb^gQH[%>WQg1R]3Xpfk"hIT:i(J$tį}l0S .VhҗJ`͝ѤC`䏪orL]!- 2@Bo C*;=2Gزlo#cDEXhKg0s9͸ϸ! ^?*0*efB/R~_X9p%Zt~3&s_ S ~˦cΊ]2ߺ2k6tc6i?=ܽĝ?}ґix.FBekc߸3" -H#׹{#Dpbp&i9#ai rxЛ5S}cs3t`[ASj<1CbP!7/_+7|X,"YZ:OJ;SDHIkֆU4JZ8 ~G&^JOfWn/xI[#iM3@u樬ֈ^#4_ĔgF`%AjʜRfL1U9=_&U]z{r);m "D6yG)?~ԇhԯ]P-7IDBݰ|NUnˑ\+ H* I( -@UԈx ﰭ [Y*%nM+e(-Cq !K!"`xlbL9B5lnIbw*E /ّ>9q1NXD, KYFDa跻smg! Qu+(Zۉ3QqLV$_ ;`f%=oVxr&:ڑn"ὰ9ljl< Fym,^܃˨PT +,ž6nFG e3N8.Au{ׯIh.tޜrF QM5?l{ѹ{B]GYEW5,Y)wv5 S$Tc #$)BGm޲K!psT"Zo3{Wd\K `,x/WG_)*V!AI53跔\KVVl3L%[>T _[RnNdX< P}QԛLUuN-2]>VQX!G@mZq1r/Ll!P6am@-h?M"XB&oh(z;ntNim:>0M 'Ɖ?o=?Xoc 65'r4-,@z4G8,U ^}u׫IGmr$3]h #L7Nd*Tl{}Կ3~ P bNH ѹ>[(ܱe%7?5{u ȸEʋ[dbvJ"k]o8Kq%6RM3!.'I ^m/j"R;:K2jE ՓPm 9Vf~㛡 V%(wJj bƞTQ/ۼ+Hp{vj+P$&£ W=Q񣌛U9}r_ @6f!rj#Ըi B,E\LX5 RMM$)Y{yx?gach@ Raԇ,dFk oj+SgΡ݈W-wE&]/A1.|J Ho#X OfB; ^vG{<צ1<uL;&Z,wRy_yQĎ>(N8S5rˉPUd@hj! 0*En8gnp?Ąceͭy#*Wy=}XTzI6 [V[dNks=Rb P[UsWҕDX#An]cB1!fuZQ-/As?eKcğÿab4O#X f0,t/@jc _h4co.<qWNЌc~ĉE4 8[N{/iwöʿ=kch;*`P:ĬBw)}. MB=:g0q] K<.RXvjӕ3y/f#?__oc0F|^)i{-(_G䵑Am.*{rr*MNDs[%|FE0$UjLmvdS6ʹ #%Ly<Ѹ8<ޤxI_RE=T>]rtnh;כR &5̦0u$U8&mq4Qb{8Yqj"~4(<Εs@dc%tQo;v"#/}{JSH~YvWH՛?SY˅܋@9PGV׸qMq39<("p ɷ/k|:'[BpCus[iӇ4) ZRSq JT.q{'LU8}[s6/F9;o: ڦCm׹cN٤?$r8_V+? 4M;'{{Ŕyѥ 8VtuESR2Ca  1W,}ΈؘSsP{iFw?s 8sɕlS>>0{3^-~H[P6}Oe*OVڜ.' $Ei4y⤪{d8ݯGJRˋڢrsK53[ْho Ļ2%{5y}}K|{H@ot~tTWS tUmeXߝ@1&h{  9ځ.L|vyrOD8,? #jjp'` 4S'ft c!ˣEf o5Kד@!#{Q /~펃?O؂x4\S\R=]]Ym{9p ,1iQ,})!"wfzW<|VIL\D,KJ؛>M{·ܓVr%D$b(}dG"*mNH Ӌ ~knV'qd ޥOOEXqƑyWvz'TAq55[YVwgӒЧ(PvDQ 3e|ک./p%l]|3MHwEHݝQ{atV9a 2Cq3CET 4{&%ِ\m;n'06zq1gdw)m00ڿD d>",,މhJduzm6ؾɩC##ؗ *{)&p0ϵ`b-o<bp*Q9~H@$ Ş7貸kb?L#WJ+R·Z9zH1!2:]P苼LO\EF؅R1ÇHq޳x<{'&J8^\=mX @UN@y!8 wWA6\:z'Qc+M;j5וo{>lnoOc5E =iWѾ<kA[ñ]mU?#ӕLʀIym6/iskCL_ j!#1)\.ɪRb_CRNM0uó*U+ \y.kN[Ή-5d`Rr0XԜUvD(;g/ຝD^)fuk,MW~Gr )'v||`Ernh Z`yT^9/I*GH2OL+^ޏ$1^ksQޟU7Iѹ9c%,ռx^v):WDrѷQ%K=܉U.MT2iŔа`4PS4Cbެ^ރ@#lW [W{6 U6[DXԍw~ e18\.5sb2tcp6TTw:L) A:`\t:CN'[F)1vZj[rnTrc^H-| rw<- sU 5B<³'*z8 j #mJ\Cİ pGL7wo%VÏoWz4mH4lE#K琪Cк;3FG9SW#p>QtRw'U\:&,#=hJ#ڨj?{cplQ(]Bgp#*e9uW[W( ,19@N/jTvGBPB#x}0Tv "I Qt C.2%(.p`_޷bLt -MczB6L}rYL|G*ϼ_hVш TH UfUߖ,{h]I; 3 _QԬ.'g͇V YHvQ-Xd'Dtb  Z: ͺΦVIևGep7X"keq;=ki>)݌h0 g %?w*Acs كZdx84h-0_2P0 'sXVh!Zlj8|>7RS!gj[-jZZ9~ߺZ'/>H8- ,,Жx@ҜAxx9a0ofʻq |()ԬS:kghLD C|"c>Q@mHi|}*B3IzA^ ۊhN #yY# jx߇ʀ- ͟E3$uiFyf'IUG:n('礘$ȪOcV9O5B ʎx%F_?M5`G* A.j:_'mNhꦃ;7 CqaHYf]O/p{2{$vCmNZggΕ0qVXyvWgHsH7P6fꇓYðkgBę[ҟPn>m 8#JfMBrbjSbbFwwY81K)e[)s.ʺmJQI?gWj3+3FvLTWI C$gd52Ѯq1_o6`srV㲤X7TڢC |^B{ўU;[^Cڸ}̂(G1t JpmȓrB*_EhXWV+aVS C5\'Pֺ1BEnHrkVvD\ZGɒ6](m-ښ,A4x!ϋ) BB(ɨ&H͏I}t-r @(H2:8w"QTE:}8@"Tuά:>[п+e w.Jh'/F'.=>XR(A@Mq0 łC!9%F*A,ͪ/,1F_ǵsPWV`(+Xyļ(j#%v1,$M)kLQ^N9 1(! _Gs(ϓp >N.45'ck" _Rr!fPK3j+Vm"vhcbAܥi;,2I%lmdЁ¿@/lŜzܺG[mLJG[~\r`=/=m  ɔ !XXm:eqb|_B7*j̘zQg҈<[РM-R;i{v[xY*+m+ ϋVV!Uj8O_j2ү''k4ˆWM`)ZߪfpQ Ybk7bEdoi_ .y)MB u(ar CL2.r)a=.D>ɬ2uFOSr);o8-ݸckO- ;wYpBQoO224w*lL[!W[uVZA,#.Jϕ=.TwIE >~1w*fw L4?bJYwOfa[_3<]ZFlE}Ȳ>(&.^?j7SN5*cxWQ Ą牃f,ZCtJoy`AʈKѫ &C)B8›0Iniqha|ϧ$nkPĎY̩ ]y@QE>{xdFɝ%X}3~ٔ{E.{5QsTT34>o`= ^.77&DJC1mVد4>)Bymdn-^?$#asz]z !PZZ(?Z=d /qy&7-c3h |' Yo aVv{Hǝ@'o#B ^N}z @=o)>;w݅ɍtL2nTm-Ϗ^|D;Ά+N^<`],8%g&_/Pjb;:Y"%- :@nHvQH b}aF fCky&ZЇFQG~9l=`DnF[z@@@?>`(ӱN)8ytqXɽuxPp{xʇDc`ΊDp3Ium]]&mi"_B(2{[sڷ{輟&fPpiM!Bs43g+9b;%EBs. ҕIvn?HQ@(!ۡз*Fe 5T=32'5{7gE$[zWM{% ^li8 ?ͼ<iZEοK\!mWi#҅yQ[fD+cԬ9m uWȦ!u!Ro/jsXy |4z~g4crwr5  Ɋ%Otc-$H&I5L!#{+!,Aw-*-.l.%2L8M]66 c[fSzr`vzéBXQM`\$?•_xݬHUYHyۘ,( [0 DH=xb-|"})c`|Up5iz-v|JUb L@cX_!}:G3@xsac@iʭH$G3FjbP\oFD9@9nk H 2"ʌC[C*.7[|H&8!3M`3&*Ju| '`WfoJNnro#,ٟep &a-UBZWi<;G`%4 ŵb{&,I<^ @\!e}%87GML:\Z\9%H$-'TBv^D4l*D'{WΉZN]aH/k}1yHj͗\J[Z6|*IE` ݺC)+O_^8,&e Gr溰!wA8D~q_oEސ3H` YYOZhFceL5!]l 5? i 꽓nbNedV`3;( ]I ֜fYSQTMѶkx]zc])yoqfćճy{'Gb~qM$SښgJL;'I œ-$ jରUj 8GklI 36}O8C lCcFA>Yߜ7tIu.dAv-E$bp앛^, RYmxFKʒ<m`Y/|X$9Etf..2(q<Sl[I"V9T3#xdkFt0,7tS mN'NL{!7G {C(kCS)Aڏ3`U&>^$TmhC^=i!Y@XϒET2Z$Ь7U@1¬O>QEwezIB;6TEدSc,⻊ڝ^< Q[qj™dF/7SZ=CN'?2z8-,-8:rAatGj%y|a`[rX+[tI7-fECFN'˨a֋bJR Ht/.ӓjr[< OW!t|*f5Os/hlwz,E'g8Hwd]wMICbD+p7} М̑]'v 0~ IS4Z z-x6ǰMZCP.m ҍv/M۽fD5sݐx# &@ˬr,'v:ytI |3sqD*"H=pr''H-W}*oqLP\>;ҎYI* ?<ׇ҃.j"ɫP9Ewx5k6 nQ)E!8Vh;«wxb)Hrljt!!xLoD=r:gA;]'1fƻ mW3A0)QIUݛQgTt> T R3O3q{M̕>`' :>I׏& ͬalBrLǸǿK]B88Ou'Ld-r3'UPG8deG%r^ETQclvkeRu)YYa Nh:mS%-Á;iieG#p\fV4_0op>X}-^')+<N"]z|(x- 46 s&G(*V8R"k6[h! |r) 1(MpsϚh3xw}\^ h?Ġ,qq~x]6 *a &ɑ,. އ *(2ftt>Lqgz.\26JH¿ zl6_5LX{K#N@ p<tR2HEiG{I[d~’9Nh\ѱ 3S` ِζ}t9QM>jrJ^3Fm`pW$^],܌| :2ckx_\@Y_0[cqg`D ZKV3-|Rzq+3nOM0qEa>|ZS=2Kv,BȼHODϫL5%%P~`ySι4.l#0sϋÖŷu"-12 a5|rp-Hϭ/98G5y5^CgqP!_RPoP &w"?O>i Sca_ݠCrXtλ)iOmZ^ |eB1 S'k<o܅1,au5i=UP2gZy`KN'$PX@UW&׮Af:HSL>+-NS Z8&zy0/[wYsk} Xz3wgzuky>rMEc@w,w:+k+,L7bYTO.漋ϐ\L6>ly;gU+i-j/S^mcżVUDQ(΢yME~13U}jOp7d}F$e>ֺD;6ńVZ.ۋ )K}/{,galV.sZh.20NGp GQY&b=l;j\N;6yJgʈe2SBKD<<.Kf@F{hwӭIK}әp9.9&`}ϱ3wa  6 PGͩ@ɪm`-yg1_,CpGLOB{n~u@1MBSmÚ{k!z(0dYd8\ mn5zu?oq ɼeݣ ]ln߫]KIY^r>=hS`T?=ܮq#9B*"I)| b<? Odu Lg >ur2HܽBzzg^mN!m֞4swK%I kP}3@ q+wM _)7!-ؒb7GYp~yYk+K- bDV]5f4;XAhZ=X S KeV Wܼ?tm0ĝY.*J3ZEd,=S9b:킪NJ̈?\}M\=2 Mȃ*).|M%KK5Wďg("T -vS;IVŶ  DuAuwըBPQY(d#ȋd(,17qCcNgAZ;x5YYuRoN/Od9.zp>z~jlhyWX㓥Ly"=`eCu}ADխ6@/v"PKg"yo? F?SX}otȨOH=M.+=в`g$q#+1 Ǐ@hՁ? wuEe%6 p! zCg6Eܡ0 *=mPXc7/Tp~)9 YR]}qYT*TOK Eգ7]  ^^v>?OQ@}%_ >&SL[^vd75SxDkJ!=y(]3(A6VL|F/< Lt<}_2zB&g ? t?bX{/=&]ßQƪe1$3wru^XDg^Lu!z!̕5Kgj65CRՏt( GRO3:iSM\t("Jr y&W$U߯Z/YTKKùAN\p9*#(/vkl󚲛wzvܤ >ӄskFfu7o# *@JU}hPv_ 38D2訳{^Z&zeı*`U %V#U5I_cy(9>-ʇd&&*~|E#Ɖu>$M]r|-& M ` @h` HCx7wqmj`0hjm#wv֭KU㘽EX( !wv_UQ|LZi1^ =p( oPP͗Za~#3lKOc6C8QI ɄwTOwelU7--acLF]VR- U{07+` 2dDWTlb.AzXqNvhv H0Zi\vԦNpFgF"m~9a4%\UZQ|=D w҆HDs4WqVw;_U 8.YgK R|"% M0OT ៮`>ꦽ8+e.!ԆI9sX0.0ncX:5@њMFFMbs˟?Ҝj~5[EX= 3PB+]P+yt+#V5~4ѷP{!W0AD~v=:?svs&tyRqv*:!iӁ6M@Yp^7(8!eW.r \+-۲?$Sp8 G8X wFG&QhT^bc_B%2Pw&ߓ!N㫆0+IpVQ\ݗ]TseYI &%Y 4 $P#sC3EEW 0 YZplyr/data/baseball.rda0000644000176000001440000104362012034020705014435 0ustar ripleyusers7zXZi"6!X])TW"nRʟXVHqjnj-&b%i*\CKA*֚:(T( W%p8wep`KBC&5SçBIkn>NQ<(%8 >3Z_Z'5so@F~]]sNL凖8һS ia WaXj(趏gv J%[\- R`/4 ԣ;#0O-Kn$e/N{QE!/IKm!}}9P_<.J$IVx, ҏ`Y"{ucf^qHa, /5!Ԇ ;#X[x9QzcK@E7z$mǮqk0YDoWR^o^ gGg/#jkwЭna}BDw;$>ە߷"on)1혳ԽI5)$q_ +W$ԱƦ*NviԼ Cm׏ࣂCGm^FsCƩ~,iPEiZrg6EEs~)M-E->?'yD3,v;+B oW}q^=?HBF$ Bo>c ty֢ߎk޾][r?*:Zs˖$FeQ(? ؼO 'NLaQ!4sd1/G&*g( | @oGRiPjO[[0fR~p*ZOxY9fXqz!ī-󬱞[> V+mꥱ6 ~)z4vgtkq,1+ʄCRqQj1[0<J6R6ˡZ1aBn1Q}^@k)wWʫT]B0ߥi[: <իЩЃW5_RU6_c%׏mvӁ/mxd+AcEu۽fywb` J"-HTT,:^>nԗmEu34gl'mP·\T.;0|K4t‚E?Q8/'-].y|+3liXP, Ti/8?< [ja o[W KasesrٕUky^_|WQ㼅ӊ>Y$At݉i4$8^K 57u47vuRH?AXІt=v V=@KDЉ<|l@qRKy?S  Jhd4[2u=ZFF:뱾zoxXpN[t? tw`xJ`Y! ͽȺ[|x:9 ЯX|>n{_o} ~>j#6tR;[-,E}&`hlRxͲLJ+w{+MdᘥIpylA;7> Y\EWq /`<섨.voLcqAU>-g 3PŒc^qr?œ}C10vӸ=uRUMؗ0xR˞(SP17JA 7# |%DJĨnV;8B(7ڬy4-hnL%}ՋcI>𐤟rܶj]e736H`k!2oXhtǼ/_!q%G/s!:SCܿkM`8`{!n(i^`(+x\a⠪t%5u?ٔh.M˱ ja%h=-[Fj 5[(iQW[D2,pkvBz 2M6KWMm&io쎜*}%VԣsB)T#VBo  7d%ϽRn ~Ϊz&jx^=Cn1{;j pzF(v,DM#}0F} 4skMd~ OoZ7 : yPb,k@0~Q܎ŗ f+.+) t=c`)P.]Y.sTl# Ű!QJ0=H cOg#Y3k ·ބ-d^w|1ZX.6T3E&>qK,Vv9F޶:XͰO }i+d7Aܞ- D|g3?JZZhqlan>?UªuhV-Mz* 0(W*7 W2ws!>ܛک@R?犎o{vv.S%18Snk,bKYr\OQF ;A2\ձZil,¤j̕p.Lnn2[c+`^pN2*&`PGf]zC~x_LFյ3\W|ɃFd g^"Hn.Mc׎O"MޡNFnsqu"Ȃwo# _֬:; UT+IRMNihrx P92S.5r(>Օ$1 Z&,fQ^O"r|u?m^c;=]5Z.c%,b!,83t#+6Klm呔K`܅ s5`0=X8^ îGpXxBHh8 nIxo̻zEfA V,zO =*P3V63, cu;5>T<Ų`gwZ`$Frأm$;FvxB#bR@IW/"FnuYa[N KT'פa^o\ [8\aiAOIIi2=Tʺײ>7jҾ\&f)@u+i?Jl(5ˎ~x@@'›Z..I=s1 tOCrG1IfzJJ1lSZBG,<2:ᷮ؂>"js%K"&\>:S 7Q i [*!|yKp'_YWXTF@C2(e`=q٦$кeUhBaDȂRW| YPab{CFXv_v/^̿|,1Rfx;暡 _-jy&q}Jaz.oi~$y[4_#OpM~*A\Q!vrH|$jYOgެ"jj$#7mSzlM*ǿ'愍M:wAfkmҚcWErS9.}t&BzXK\w(_ =iro M_̧=BjlVjI!6t|ݷ;u Lb]cT*ǽ{4&43Aj6a=`ywB8^QxKM U,v+_fw$ҍR_J7 TF|d*+&Ak4فT`ĭTR69dGT3vދuW_]T쇁ԍ eAS D йV0]#[ DC6FjvVSԡaGzPO/K4T_ Ғ.DB0+d(t.?~c% hu*hvǩgGf6k'I3Fϋ7 7 eudY A1<8 qէ`o^k끴7s[QhZLw PÝے&DP*|N.W0X2l`j[9V7CEUr-6e|\e=$X[K%4w?栊~}o9lo#ނyO@3pvgVʬ#_RAb@W;MKַmIu|RYw 7z56{_bM `n|1ն0K}X˚^OKv^+X-.[p %i1 bp8+-&j-QX^MFF3o͗)"nVǾ^ՙgC2R"SGdD]ꒊr~+p3Dot( ^"}c嗢l!_,2)HI\" n,}fcC39W&y˜|SƿL2r 9po.~Dy)H!w[u1!If9[#MR V;-d_eP &dBOirI swlaD1[dT9գ>bݿ±o6;L?MuUCѸxI2OKQh@) 5l# !y%$O+>NeSM@NϦ9ot"პ$Y$zFQ6- OsO8r_RE60qrpR ?Evws g/ ED>2Ts4rX \]!BKg){uQ!t#)K)X XdQ!a)z%6[rD 7R> !#}0G:] = `H`hJuju :*ks/~ɺަW|nQ ~tB s7yp}$Ty&hCbU]E5MvU[S04o< g^BG ʥ8䅊l,WMʶ }hۑqCrId%H~4 c&ZŊo0i!w3h1G|n#_c=!=^cIFq!*()9@Y}m%<`kHְ[n2خʋj|AytV ?3r":VM_J0hA{g1g#,^̀'>28n:=Qw:QVyk]zk~ۊAs{?1{˶IMPCo ۧHL^o[p6/9NLoZ]̬n$0 &V"iwqu Z 3D8whf;3"o 7qdYĜ\v3Gw"?w/@_cۊS#=/63iuTަʆY]:@ a$5$y].&w$(2KFtV FCӦzM734qPW q_ BY7b/88Kh4`${8.r`nT]l`8Q Yul$goKnWm:ůI@q:d #׿ѷaOftrDP ߴrHE R+}/gչ)LCG ZÄhGx{OppTYЧhсS'"}[c/R캮 \ :C7]c~ܑza:7`Sl͞)Rz1<):p?K| )18px g ٝ?fД[I1GoZq2 "4#D49,ƙA9{B/k$ƸBC#xnۙlEgE외#s]cPYwx-2D /+yZyBX~lE8Q$af3=5E.g`n}jx/)~?os.˲l6 ;-PdնӧPb?Bl<]6_>e] $ 'نJcDZ©@m={4'υ|6Ez0ˉኽ?ڊ _W=ӃOMO{ $- ?dpr5Y4Q,TNkJbt]C0܂6' S19'@¥rdQA,D{ 6񙍷q}H7W mSEϛ8Q(N1$+@!7aMI14_G(-&%+>%rˑ4 ٽޛHEj>Bd8-x$'*gaq;/<p*J\ tRQ<*w}(*0Ēf;yH}SVCLs22: UM1`&%sс=Mk^'yzntY& gҬo;qըi`ԙ;-M4+61~f'SQu9."wB^v󿴫HdѠbaY~gD)BR ySPɣsz%@У2,M#[m7Ɇ^vJqՐ^-Q,ci¢?yB(9g;IN$̞9#z}Cbbܑ͡E~Q'<,ϓe{ٚ`"_nP#|&Bfx7lH|}meAB!L"BW)l 1Q*&` v@;j3޷|dyhl\;o]ҭ&CGWՓdK3Hęֻdg_#]Lݐ  :XIo>k{&1|LD$9.PjU1Ulx|$DH}U@ +;8 @CF6",/vKܽPȳO14!S@l !t@V~rȷofIl_FF&!R.,tIp-$S5U1%fw0}DYH'Ib (㨞' `la dvā/& A 1^FcD-,#l(oA ܄^K>EpQ7[)QF8!V('n;淳=pi~onuA 1peA!?Žk7#\|&7+ZiUp s7iЃ 7I;OHb~4F^pj0&,%e{URqGvg/D5K1C'.e)pNȓ4;za(ݡR!?-""Z0ں4OX~9ՓkDžZ>li9 ءݛi}8$nh’|r'yo)T9$;fOF?>XG9tG3: C^I6_(Rur0r]qyh_}DNS E32t(i2dMDsPx9-X׈ TɧsjH2`<0͓t{Qh2<2oA:UVg8kB~31V'6bw^Vc F8eUj)@*vOib8L$jz/w W딙|Oɾ"m_.H!f*.fs<9tؗsnٮ[}h Έ',akn\(T?UAR`kc;ZgZ<Fs#ߵX-DojOv.^cftlc+vIiF1vl"S\]Ujuق;# Qj/uzr|-j, /vMgׅVPZ1saB\5Œ:l6홾FveWY̋txh7o"ެ f,hӬGr"#1H &>gD%@Hxe!N#!R{yE0 @o vt*\W^[p4kc(M0M}svݯ)Mʥg]-$s,dV"t++=qdr05)%hC̛aV@VS03 1Kv~-#+'+Il1/8hou+9$O<d }1Э*N8"!sGe*,}gJǯi aی I6*wlGgڸ'+oBOחOI_6y0A*kؙ!wzAmCq[=g!Rb"fJy/"ʮ{9m_t,; )C[6?E6ǗN 6h4$piM& $ekC-Ϲ]2f.e&ɀ|;Œݞ1.! GZ03 ʒ%L#Oh8˛OCR@92*f]ȗ4T-oWr2F?Tz3)W%ZR"*<}κ-TP7aYO?$'{QwGJ')BqW^ Vx>CU9[ EKbvsr[::` \-nlfD2&|ܡ.@Bԕ7$,)vmݘrb1˳[tM4]縕5oAZِa҈vrŊC&A@=VGMt遲 #0hJ@Zh\M;QA umnPFaſ0zIKj.8ZL>-Yj!@ o*L$+~rB ;L'{gIc!vz ? vYңuۋmվٵ<ƏjPy@c5ٱk,4/Mo9+b!grh>"Vv9W4EݜN_Q'ԭd曍٦/&w< 5ނZH]+XZ2Ut7oh+>zjW.> 4R0.[a^9 ܍yԌSl>#&P%_vƧEŪ%ߏC>@ܨhfqٖx@LJADyٓ}.^P h=HOY`j#)G/ #j~lFIN)D 1B nx;r?Onjͅ"܉z}b)b"yG.iA2f3<f=Ad~ײ.3?PqGHnMT=ܜjW$8'e*qG"Qf(ߪ89"3> ֽIZs_-٘m7ǂ3zEa5 \G9j#dqLWNP $Xb'Sh!('!IgWcgvrkgC_?IWIԟM$Eh*3a??5BTΚmTtZ܌X\>ؔ+n@ipZ ϩra; \oN&%'kؖmпXX 3;݁r('LS$w܅D 9t c4a[N"x:"U-'Mre4Ix\'<ќBZ0¸\rnkStx>cu#{E̗Й@U{ŃEĪ۫!DVe7+63a @|C^^^:ȶ+By; K`UVeHpCiT2N Vs)`MpuZs*d_I!8 %U5yPE"> O]7W\IxW@}e 6M] 5F縃T:C࿉ ^dw[xwW6x/u*E{QQk湴˰"p .-ݖwjEgZKD$Feyf׭+M#}wЂ4|5W4+αZQ7y:!@:-ȂTga:NŜ!"5jt3:]3s}q2\YfZxUNDEhXQ? 6M2gu^+>m}>c\URrp3@6;6] UEZ6D6ry<+[a3"Ҏ ?H62 EnM9!%/@fq,7"S3?^ߘg6@$̺ ȯKB-Zj3Mu*q\kBؚ-&Dq}` M XKn%_d$P3R0=2K G¡3Hefb3^Gջdʑl)-LȈQ؎$͠lGcτ)>zCPN<x Ψ(ʚښ0KN59R[CW4_rkQdAu`@sܥ 2-voINxZt[߰H.38U_ln1g9t@Q(!+V l[9m |w=^Bzox*\|uiqrevuV?Jg+)逐5ˇ%u eSLy U@(<@:R'V`pc\}n#£8AΣޛ1 #@"?iv ޫ!92!Te9JBa\L:-%,KN1z|g*q[ĢVv驷?{x/Rxɍ 'PUP^jd<1LfeN|uj)Ȝ)r0nm|mIB耖Y^%VCN+C*j;7/t=Fl+-ܵPG8Hr)04EcgmHX؆1+U܅Kc.aP{Ϋo_ 5:fKBgdķ40˘<{l%bS}䣽Xπ?IFp3kP4T-xB_Տ<׿ݞVۨNW_ZbRz*7VxٗD^\D-'ܯ ;Aj~Vcx)uHG=Njp$Bvt{1ԖWa-=)-SRTǣԉN}m!]/*9ir!kʨz^m.Y'cwtOǜFb匟_||&$=mI"BmB'! Ͼe*&.Kq!D:N֎ӬuB}Yh|YgwX 7A u8oz荂!jDibfeD~P5!HYƒ62xKfTE[(S3>4S'*qá0n_xKs?5;W~_ԕ& hsGzmRcl+nQOft'_LYҜ,Q eZ plz>yzK%XmGEcFMi[ hME#-|8rC-&7E_F-7Hxp|ػivW֭]GѼ'q* 3آOk̼>d5꼽9}t,b++M^#Ze3 Oѧ0J>rPRc'2} F24F4p`KCَ\T<@6DT3GӠbŐjZvTx>:25Y&pkKJ5X?>]_ɽTdkUaWhӒdb@C;#~ZqvHSƝVEj#^  >ӕdueHgrG)B ;lYMf C!> Q`hyZ:\8:K]94p2lfh M g;x y<}P{z؃U%tFhYۘO@h5obX0p {9s L<ϡ'6ѭ%0ɸ/ywݥviҼ ы<;{6W( (qe}RpϺ/@e 4URcP :8q7Zx1ƫqRK"N#9 րvO8U3➗bSBxDm5!!f'OJ ZƟ Eڤ1 ŲuHA@E "74EeZsT* =:[>o<56&Зzehb@^0hވIźW٥]fBSA_[ 絜+MSGzK̫~tqdK N"n>H) JW=yuEMEY:OCb_FkKYpI\pl7i[5bb38)̺JY@Ҷ@)`.<)BD됑/Zs /Q)D]B4w_3X_Ao'…~u ezZn-|T{F齜ՆDٽ. ,d%&zccL2'P.IuGqcW'z{ޓfW'Yr5ozQ1 (Uud (gL>R5=]W|F\rEW6UK…<ιӬhIRW9?n%CEKdq) Ư1(C8U{+/?xy9K i)&hOtMrlx:>}%K%N>A[*UNvЬ%ļGGc>}K+ Ef2tD 4vx_Fֺ3a4(JU]pVPyqڶ"Y@qL;C`D(+`c [̄%#8%2?&_W$.ϲ5bʾ8ZgaSefSaO Y!a?T건AusQI+ۄ, H}$bsM=v#/avGo},¨'S kb.l.%R< |AV0P9 fxe+5b~pu.6)uGG@1wߦCIU(9% clR?],YCk}fQ9:9IQFi*[rG=I!_+2'܏]~"R#0?;O.QH3J28?D}.).QꍹQIp~;)L)hG0{M dZMG^YqP7Y T9!vB`%6wőnO'en3Sm5y`)u>Ϟ\!=*nXWv!2\NDϞ" e-Vbj,G@x|eė7p.k:*(#t;*IT) 5es z:.')\O7Y&+4$pyH84/;QUe'Y4N0-NK(tRV(50?Ycf.O"1UG^U P)S6[`S;(}1]1v}AU^f<+×`ǝLL ܸHG/ %Z'1ds}A-ީf q<$|Uu[BFZ^r*aՁ8H dVȝLMퟅ|fj!9XqyyDTr%ٻeStRbD웰Ȟ|ݥܱQ2' ,3XPzN̮sAfk6n)$`6Ҟ4sU.V^mzu#shEz -U.K{E2'3":˄6AV~ >{3.vdB3Rpg(HPH{&"o(bݧb,Sr;6z4RϪJ#Y+OaZŷpeACؾ9(OST/7U<tt), !?huHo:$mRPrrg)0/ާ OAƉa&zNH,^yqU>^on1Lp@|CZgE`$t;"Q!߸qP 87~ECs~@}o]g4ddYEb(b j9(c[&E%QegIѓUcµ12~C:K00ŤngdJQA}LIUb:=@a/`d`sӜJ7sj 3ò(C8b<(idˤl1삐k=;)3B QZ%=K h9yVskmwvM=̥1l/K< <#F_b|"5`e.3]l`XnO;(TjO‹6+di[݌l4,nzerxtWuRuQ%guPwkն@5Ѕy[|wO$Mp3z4VE0.~#5ݼPx ;w] k ɊYq&ʁ ӒU۸խ9ᯂuUEَC[4F'^Ftn=Iu.WtuA@\:D6?uS2Tl(pZq, mlއ{k%;?2GRn:pM,z* $^´n[laWl &b4g*4xT@)¬:TH *bliib^qڄ7)8&3&^.K#LY8tBUt]JotPZ2*Dya4I(,kۃzF4yU^" w|6=/֓9&@TRX4{4.uY%f!ıg6?P<|@P^)h~gLjȿE6/>z]] `$kMExyMJ [Iǝ`}4Z35j )*g!RwSC# =̍.GG2|iX0_^Ǣ2w=k8hb3Β#s <:eq: fhTslco=K0Tl |OzcǪϹYw`7UPrR~[- 9'Zn]aӶp`RY0:D {.'H7tOi Wig.IOhsSϛ;eX$+iή~%WVxM}Dl~oGdo;tԾ ;iNqh;H"t_T%+L^n &j=z!}jw$׬Q5&-ISrWm{ǡuJ^\"Wؾ"DeܺW U՟wL^ϭI{O"-D/|0;y7&mR]Rg[mC8dnKl">vj3ybf/eB;*i"XYk7w0zꁙcr7.MA&-Q; ʁBj,t'ޟru;@A>A&T۲!5u'dAH;kG[0 ߚ J0Fr g}TiXE5S-tX[Ľ-Pc%G57tZa 'AqRj(Y 6LpL-| 1=!(F >֏hAԋ=Ȝ 6mo>H6Gnmj`d 7{`QL"'I!>"1$.\nPeND:&yUKQbf]OԒl%6AFxt!EɍZKx͕IĆ: I$t7g0js_t %7a@OtUs-C\sź\&-C09U T&uS̱} ̑U2>٨T {q)B|[}~WZ.6S?@ZW֘QTRXQx{CLqAwĤ3&-M~b霼 ֑-'e>Lty`x.a=hclXȼ&SX9L2U0s6߽5*W-?(+II#Bj7Nf髩i xB2!9dA?Qs(1o.ؔ%J,2*Bz uTJxphWIPs1\o!S^{ȶ6c1=W8Wi YY{\9?g7hG,v93vfk~\z(WA8AܞEw ABvjHSƒw|$[sc Klg#!GUWhבb$܏ Of2ÇHxő,v_\S^7R*-Vxqk6y\ $Ϣ=$4)%2Sȭpaiq=UDQS,e!*b7:L/jUקҦm%݆qjNV6 >C`] .]?r: ȣK _]bn6Fġ-(΄rJW1{YpEO` ՠSz>8y`3e{x c =M2jYGAFx(6 ?`tj`FH KY_[: uf3PJ‹r=ZܠR:q;^okX`꟠t6B?!rcNt& +Eoƽfl| %$V!bܞ^zqD{LcS e[D%$?gS.> R.oG`^Rߐ|K^w'ZGW N(Ѫu܃YN**Cf;|y?|PWa%M,/[ u(߳Ev|U 1'udm i, "g!Ȇ%bj =/!< 7C[ophn2pʳJ8ޜpuRً llaUM(ނ>?%hYw PwΏ.%u*{9cv;r .Sݵ F Q?20?'$H=Hv(qN roS fi[,ÌvFjq﫶6o@MRmq1+/'3d]U`Dv{~_GU`'?ޜ3H.r:4i!#pE)Y2Zmj D/|P hsy,?Rfh\w}hR?ɻwu4E>)hEXתfS"rU6\xX,n\5p1pIr]=3%Lߓjٛm"_1:esh?д #Sc>.L/jO(h9 %D @t%`x| ¿uQ5'햨7Iۖ\F?fr??vW+hdfՏ<& [>eZo@Mpn]=_|wfE`A%$WS+X7gPYSkF,~j(80{} DX/j_NL?o:0 h**GiUpLД SҔrXmK_W>F@>TQ!5j oOb"oN>?#DcSwy;9 Ę YR" keA@Ίpf'֨x9?t씢͡_z /n1}g]q aDzjLOڗ^j-#^$%j}z,4tRUQY0`*k[MbG!%+e:T7Ǥ6fF&iݙ}3W^m@tQ* 9W?%k5;% [d+1|R_e ӞÎi%H sE#Gy7H) uv~MaC'A!_ ĔN|DТ Y*#_1n:7 6D:`s׉ox0H}=2j K뮅Y~Z%gl?nZ1xMVF5}: foi8.X>[aX䦽.LyuSnpLE 9XKXՈ5êF}a?Bd 3}zN*qU!>dR/}g]]$6 mr_& 젴 %tYI8Aw(Hpcޛ@e=?az§wSm3S,7(˔7cq7K n~AܓI,brrFHBU;\v0u",N.j4 6{Ld# J .{byón>*8րu F_\&] Wp:KIiʒͣ4"P= ~a$ϵ3wx) qmDb"^KA;Rq= RaM[[OY1| %}& 9b*L-,2wt$l-GCE4G';A2͑+02GFFj/Krji[f|x"]ЭӐK["ojNO3 uFKL}v8\:Q6I gǤvWt#w]φ`FxޥʪuySi=ʅ}-vju@^3 ~N2N2E?`nmkTttqM_Ӽ{u'\1 f>I!pFqt i#_/ӫTAd:%I’hst\w(GvBW]bO N#xB , 3`&~ӏ CcU׬cy! N*ed={RVzm ŒPAؕle:yEf^1xWaBy4!bf]͏g*q ۷olj1~+.''_IhmʫE Ad密=tO8Bٓ'׺ob> `>6pEO-6ͨjcvc9^_Dt`Yڊ42<ه7XX>1B'$I%avk2H)@N d s GaEqHؿ)E_)Xllh(o|s&kL]|hGpȻB٦,sC&R/GJĻ;&Cuz^D?:Bέ筷x 8f#]xoƔ63J~G˦QDQX֍ 1 9;2s4]z:GP9,Vh;tD*,jA4z{NF< ((lK9=Iw۠kS3ɣM-~Fr~9ռYb B3  Y{Y`'`Փl[<5-n'~YuN#Qґx"Piwĵ۴D)\{1~!WB* I":^n1>U=2, kQǧ#otq 79=k1n΂X>Uཌ^6U/vROj,"jvn~VdrMNjVh鷶'*Gh)wBGXSh],5+3Nq'j-@$Ρ8B{dGyʓe%Wa-c'GJŀ#`J1<ćRC9Gv %sA5U+C}I 4J8L F IP֠-I z!UCCNmi_Jzvnt;╚ȧZQJyo?_֓j\Qyf;>#H~FXP@.{9~XDO NaM\|] JpxXWb(Ǹ4~r/,{v"0hBI4C\T*NxbW a*,zTWF4͸PvkVrD XBMb_AP7g |JM N9N^^B1pi_<ׇdl|UpƐ)wA.QMn\FDRcX6ˤvWV Eei ).rM6cyΪmv5 T3;JyoHϊvn;nvq]T\`{{MXTde>غ6v]\M 1r& N!$[5žѨ`%ISw{&߳ =Moe5 {'2[HO05`y]sxLuT^[7`yp@<j)LC_S.@Om*v]g7e {M6㐒7]jX<̇Oq:k=~D +-$LBBk)Qo/vО'#VNiScnu`7Y|ڶ/Bԣ"9Y*N4T>Q!-<PgxFq= U A(wŽ֧> Ed8>! p ZF Z+e k,# 塰W`K`g`śnXjD2,s#~ ^[$2t"&Od؈`ԁD}rkv>3l23sHgzL 5E c˻9dEXK9GJ}ҏQZ`!`.CA48 ?&SZwc71#LgTY K UqIXW0݃L31=1۳KN1y_S1{):B 9pץs~A1nLhk*} z(|)Eby'tP[VˬFwHKU6h*nŲ>4|1 L 0Pg.h Ph-G8L3Nr7?m\{Pؽt{xyyԧr2ˮ = -P#rmNzsVGbWs:zzeK !|U!DT #O*( "~i1@֘|Q5(b$ҏ (4N32Fi%J`i+\ey$3vbeB aųt"g嗩\ uǽfacqo? OKRH8SͭP$-f8Ek]o/e/0S bXӒ@F).QlI'W{o>PI` QL[v4<ίL1w;4Ӥ{DO̞E4{ 0à(="> Lr*{Ϊږs G;:-ܯ7Ķ9=P'r4(_Z3-m9L^-^LSuK(HV ! 7“BB%1/GXQO< ]}ZXOv J J]/Ji;~?-BIvؘ{HRmNCEX:P~6zD2[ Zϐ^Qg"]{b쾢B,c,R!òJ*HXNVji–D#g>8cf<0dYbk}u9Gpe1;;"i2nbJvmR&{@NJzh>S?fR, YHF4Iy"!q(mv^35M5pZSt3Nc%Nb,MY@%d|> ',3K F4tr 29/7\LP Z ?/8k]-xߡkT 3詈dndXHhGgnVlq頏*]yȒ~WzX˱eW%ńiA&0P_]?v`Y#1=2Ȧ0CY q0Ny+PAfK!9nDf>6bކkpQ8c6@BEݽoL:Oz#IB\¹l{wLN/wQ]v]i>X{(XEU]I:UǓ*saM gliJٴ)` ~@0\CYq~t&Yْ*잊(&g4,GtptFa޸M^'ɱH?ft|O^ΧUl>ՎE eK>V3xФ5: z3?mnEGgEKg͞QbXbVVdQ ?X U*S5aj `k[aΗDNbEO="qEBd0wzDaxBx @xaS7t{~R}εϣU5Mq9&(RCH8+c FvGE`Lr5H5bQMx,#ˎ G9>V7ҷG+Ro$J4­~kܶva5a}1 ޭT /r ʣ[[fCR]δ`̚)Pʚ?qʣ#$dZvfn4h.-%:Fϱ;hmw k JZ[ u J4,Y$xwh24RA6I܍D:hxlsy\[ctVex}-{cU2u i'#ҏ"grmpP,ࢮ&SuFlIA-è 7] Kٳ5 s_Yҹ|ܳ <$xakB]8{ִ}βpZx?}0X\V)ճ䧖#pSPIW'{`O21wI)gu2j9Nϧ'^oJ۷ҾhNk >LQitU2M#R`^mʐ&l±'Eop=nNJ+vxmAc7T[C ?U G'qn2[p:Vʨy!>ۂU8jSܣVq)u'X@( "##ґm=%` Ifc@5||η["'?~jT±YwWXmÆ[Wb4 wubҖ[@rbk8:.brXg}l1(d9 ,()t6}'n"Mϗٙa2"$%328{C>=)6{"9.Ie}' 93uF@{`la4JN: C8 c.Lb1uw>'#dFUSI&y*OG*qq5l< >& 0Գ_E8G]; 1??!#!2GCľlėkY\kgjmj]3gB8VC*(o'8gY\v{)k$>R·>]!Y5Xo4?nE+͒VKû0NT3tDL*;Ft`Dl$"Q M"nv( Euc{k.!]-#^y@>ct#ѴG׸{?k~F v7H˘ "i[xR<ğɉ ~P+|.w&('[f9|` А|@[l:= XI"+_<-r|$jHK"-_ufPM:59nÉU>fB{N&)whLO%p >d'\>0BX+u#d]1[f)e܎}`jxA֯bh?X f>W0-@- eIwjqE4iq/w(IJeAZ]Lu@CKjv[E9zSET+$%EWj]RoFvY-eZe]%ӈdӈوU7|4/q pxƋlŝVkyK9˥w&䇦k[KM)Ю[)|Ӓ . x,k0l5'cH\ti'/.mFu ɄQW<|&'ߠFT4Ez%YGʨb[$mSKkoYL/IXf IEߌaXH^JwYWg^q 4 c!>5)b`PeGB{ZjfG5Qf\LD2q2El|4zs!enm ;;'92p_)K/e5 Hj@&d0C<h=vLdwj6=NVɎ; .r<Չ6Kf.Дn_p'656n*C22))GWQT^Eڷqif13ίVX oy)KsQ&ahvBSjFDљH8əlOCaтHXhB.rD[9M[- AnW lKyq`G6BS`nrMt qR522~ب+۫ 3Uq95+ȼ}Kx# {6޸wX]ڹ2@.Tb X p,i^u{ъY.[{h_d(lb̏iY#ka̻*ke+.O f,- {+ۄ&$܋]uVkRˆAC0Mq.Hubtl(wL ; }٬(L 2QfNVd"yjz ib~Kc[ZRhRue"Bв֪\oQKCPBW$ ^<#DV&fpk.iWD A _beKRV"T\0^}Q\vn qO !2rݢ@vXNyj[CN *H_CD'Is9SԹZ*uFIqThn 4\ NAyo:l=|E8E-߼g/:.7{\I6 \ƍغo@q 1D"KO}*[pnQaR\X~DuA UѴV <զCWrŔ+WtFy5ARJW7h=<:!n̹W71ǼL$pw=һ@g*Źs" oB8hR:~= y35N)۲^a܀^UJ@\JFajܞybs/a>O+6nBs:,} iۇ8/.OT+$fgP%%BkV{[$ov:)=]aF?"-2y''NyμKpMYrZ #MڑAoۮM@M`@ˡiEAO0>';Z2+o%h2j+Vs MڂO/OtlA`vr΅SI5xP<,](Cr9gb.}e91^ƖD h0BA{~Xln^B1V?k7V$%_Pks0؞*ԝ-[:"y3!)!ݥGF0nn*1?C]#3xyzQd[8龔ZcVӖ qHbV>3+ `4q*ozuf;g<USq}%8-[}~ϜE!] J7 pRp<|}A_:JD/rF8#ߓK˻+%zjLTlWv)k77raZFq : c%U0h6MG5"s2=~h/ wD)8rU^nO-py2BNQXmDqh(F U, c;8ѩT< 1FQ'EqX}REWb4kJuT7?NK=u7 UQCZPxpNm&5}옒H1a=7Jm>YI!lu铀JDhKA^uJ*9K *3#<12t Ga0gV&y\Gfgz60 } ^wb屜d-fSW(ӓy$wl6u\x2;ZplXGO`*~uz<ʖB% +gkcR_8+ﰎͭ 0ÑfluHi^s3ɹGV,5>g Cmes -Rhz_7=#2sN 37C=qQ5 J/RX&ϹLo R26l{6$ܪ(LA/B{ƕj=|PivGGsK疹"m+xC(b +W/eld~zlX2+UlӢt=ޓL8/s(!w@pM`:loS/zyڳoQج<(ЋdNG4:;QV.wCL#X 4*k,v߬Q?@ai@yN"OhWTt{Ɓ7hP܂?G^WFvզ$zޖvzq55\b i-9K7~@6p))*/Yo(!K##əo+pVZt#`70RL{5ख7sv, *,i7x_UyvC;lzSR&.Xf@BPӅ) 4ț:RUuA;.mτOJs2'-ߓaN+|B%T;=()1y(F> q|)՘K2Jd,3!]`KͶW )c7 /hwv݆J`WzX;'P"]檂3R+#m*@4^՚ ϧa/ >D 4N.5eIKm;W7m&V Lk+V*>j ̑P$ar*?P/J~2_,Wl#g<{{pL^9@JS*DWe9OXᮒIv62FH)B-4:(DjhPssA ʿoMNXZFfuT`$jqf li!6V@#g$Umd=죡LS:itבpT>Ki0lhUm_MI 5l\L5ڏF\{x N6{QX.xOw*%wnj N[/uӠoq2F§3ql}$ u.ah a.$,VcIV}6KnK|^{b#ŕ#<(7.[ GB V.ե,H8 ud<DyMSKПT+ңR+d-5Qe$"9fB́EsIi3OMԈ&7nAi~]ZǂUxؾ.:ȵ@u@x^)?XH/f_ {Vr3i0Hlqqپ&2FJO?(U5ϣ:'h7 m!&b/;,Hgh;Mn71N߷dHS4gWC[>OwۆE81eO ͙.ݭOZZ{py{6GxaɸrHo%ouE->q-uGrl!3ad(a#Gy|@vQ;ѻ\`5 ;J!teY\BĒ"xqyPj_50kms >lz@5۔'lq#Cb)k 7wGց~}agfc |'#ae1 V|v |\*W^۸Rd1cʙj]#MN(27 {{{7Sv>8P#g1Iq0 s0)&iVnj_zUJV:;K-څ9˩G,~bf!yTH}9~ykzyʌDbXYCy`{`L@Vq1sα5iBWRH G|d4cLB Ms kkR&ܟzk'Ug>DyZ5D_V5^ rxkfn4H(G6'@eu9KS4VĞ\ p u!Oݾ\0O}П&*뿀I[;0'Oo,L9E4d@ x{%t37^-t^ {-a ~:!QoB0eVJCsBS"&$taDI)޽$5֫n0oZw4. ܷ'[bclS ]%wk֥޳.$bݴ3K̦0}Sr{L4 752Xy)+{>V-+u_G 'Ă\B2ʢ 6/⋪ha7 # n T4ԯc'~y8"jZYxW_ *28Fg/!OCwt}-ߨ5Q3 *+[f4-{w_k7T e6<5),, nvM61Ix+|-]]+{[XaS`W31oJ9'>. 5jW~]^jSp~IXg]YzM: {{nV=]޺kpb\X1ߓf98FJːksn {Nx~+f)8퍒6{>Te @,admDl&kcwD>ɄsBw| LRG0d֫'JtNQ?3|8 \I[q"`}%OЫICWF]\1._!3o_ p6/9"S*DXXV'M26Pqx&Gg+pri az`B2{|Mſ΍ hDvDoM6cL/H( Sr8߇[-PMa%O z+ Heb[_ށB6xhTLV䢀c߫ըsrNս;tkX#✃av*"Pb8,3e9Br;ܦ,[&v=Ae*Ɨ36/4?K]пFka4uڥιt-&UkRqDkϋ,>e+et;1#hv&c ֊6Ο0/ 0$]鵰VR"H9EEӢĽؾkql :ӷDg{_$!o'bnȏ"QS__?4mp6= "&xU-tUUQJ*!pDUi:*chmkK;;.;̓qk8 /#lHjWa%(Ȇ2).>0tl TdRp8|[>>KݍRdI(8V=,t>rs*K#||2~Z)b9Ё/]tv!"*NxEc 4xs~TCngq_i0iHv&"Q Vx(}Vx{NcӤPuԓt!@A[ELNToP֯L.8yqxeF.׼y n-˄ swSjevW>b )VHᆘ6~Jԉ%աx6\eXK'\f#낻\48 u{aN7qf"%jC9Sa+dur h+雝"샖;D3Dm&R >A׽* a,(כ FMQ/ JI^Kc$L ͣ*=*2Fru+%J)ΰo,+Q##EObgc.Rvي'u$zk{2(u]H ~YҬQR@ϬRgMۉQ I3!=l5#6#/^f%><.R*je7ю);,TXXBk s'trAVwJɌ)i닢q5h&Ct FkRXY8)@"28TpX'G4{'abf ̰e?2bZ:ʚ5uia B lNJ4Q`˦JX&/ `#` `\M~;q 7&C_|0^>]dw6ZV҄H}tᖶwpQ%xF0vfJ_ ~=pԅ }{gߕp["U<4| I ktL~ ȞV<MiQYyXV !к6l Ԣ/O&WS0B!†L4]- ]`y"/tk-V:ڱ굻T0oxƞdԚq~f7i!#GKEz~lɈ֦ ~e:O N6wH&HuQ Ƚ&UTeB+8nsz MFYȄ{ҕ勬~U r.\6ePCH`< f&ȫ;ncehCJ dL#AB Ië%UsuR,"鸚cMNT?4XHIdq/KMcz5'uڒQ]R̲+F5 Y=kR<pjϧށTLRH4<ݓ?H׿:Dmd5l)ߒu$m4u.NQG@^u2X|˕ܷ|X]4?R1աC?/{(0%֍R 5mN%}RRKLڻ11}+r8̽W:SNBt(+jz[ -pCف&oonntꟂ^uWjRV\P 9si(Vr8M r_肷 r( &9+ե(yW@BE.~d)s F9 K*}SqqI{Iy"s"}>,ϤM{AQW2VX8g?8%qQ|N0L|, -cV :),n78rӦ;9:Aé|M=Goȸxf&XuҌOK,Uvi^KO(S)ʐӇSkt( PIA2^D)Tgc^HTl iYdkάaF#I$"Vb3aB$WEQ TMi= 37.KSWܞl&.ALrBI%X׈ceU>4Nt%]3NXʶ^LJÊkCQ$2M< H ]0Q18Sar- .[W̨3I2OIAS@pfDtº4>wT5ɡO8:Jb~K\ ˴bcI5!A@nc)YP*qS4-k"c7hWC#dHmVdJEMM;o]tj}X4qhY:MWHzt?9=+)7]"4}4/uR?YVŇ_8QS3-ar/$ᶀ_ {]K2Ik)j( NjV _]V_hi~/InSEI*˪.!(~ ]ە7d2̟<.&{16l!DZii*%qz/֍7a] JNuB DZǏvhg+][7c]G292棍 \z;MR lt$h󋥰Q(1fm]U,RXɢ=걂zF\5624¸=]k[Y{xmY >ny2Ƙ^A4̾ؑU`T4~,Mw6Z1&OKn\%d(*\F'2xtsD!b6}J$8,'&ӰU-wNx 3:C"KV ͊3O4=FAܯқ*nSuJw!ԟn̢li\~K s fYC,+{QlSMW+XT6~ mɀOKvm+*|g}Mdg7?} 8jt@ԚZO]RAMizOmީ8c۩;F)""◵fvb NF / rXyCt]C^]'&pYvm8JJ޵T(p-|:`SyJ5ayzH|^6}/8e+V@H| Y$Q>Ѹ°$>CR)DS_^F-9uN2aUburp7%IP-KSWu' 4nJsC̦)8yn:TY1|9 Bn.p)`زʨq!EН_#obg/81+QK>(D1R~` M台 Dk5`S#N^ؒ̚ܕ[gMfF\cmʳc>9@Z#ƍq e3t osWWP]ײbU9y+ wp_qE^bܜV9rg=X%#t$5@&{K@wjm0eÍ`ab1nϻEG[Uvq:.6oβ"kPb7L,ѡtoC:H>ůQL~JKvJwf*1<}W8^!d?g~qLathQ %a,HL0=\cS ׂfKm'Fk;7m)opb Zƙn^ʴDC-XPV nRrܮii6뭰fn^+e wU q tPm>z3vz6}t!14ڳP<>AQD΍!+}33 hWT:vDžgi9'˫ E/X_{˖ øַE˻S3΀ीz@gU+BcAX|0+qﮉSjtݸ85N/WK%e_!.e G1fDap(C!NFm\Ǹ39P=eO* jut(uSWxMzhϾ*ہsī%IZ U@6 )mƺ쭅c{i^#]˫mӥ*x:H4l[/M&A?1Ss(:rh{^hɃW(S{zZ<Xu*\V^/TPgU}8JSNlo\s{ڡ[v55_;uȫY͍.a5{zsTZT@eTϙ+yl_|òF>aPĜ p\y(YY{uXH"NWT7Հ8*!->f$Y#1e#Ծ. p @_2f &u+(3BCs@'o5Q͇`{sHEFx}Iamؾ֔RvnﮨU{ۨKcI}{~dNt{zm,q`:nfJs8=kY<U򔮴ܒrJ rD#Fxt"AÒ'Te'$J&Jq|5k>b8'RHM?1 5GF18x*$|_(\I֮@n3L;~SEXVcʚjOhOtAȓE-lj,İ?DWP^lͷzwvkb2%O$w#-%Z.XhB D67 x?J?3& `ƚ#?An[s澔 8. }}M/E'#A=$a6T}|k\!Y_bevρ˄B p훆$>ݫ2}84@aֈҬ]Ah BK+ !؜#s{$tU [ Id͵>gĩ.^#wֱ i,`_9䟲XG˓DR@^ː4VEI{ ?ū5/6ۙR ;9*M[v$З(5[=Myc[ٴ=]&A p7[Z܏W](i# eh*B7Yj1kcN kN;"ؾ ,=@/ӄ̳r ^ d|{FF`EӕC*C<]ӯbCP^opv?7d)}Czˣ,hH>c%poFBG63:8Y0\$0yGd*@"m//90qJKYdv2m[hf(c/Ʋ𬞡_ܳIpo('S%~Ԟhy/E)[@(ަ?\yc׶F2LAuݿ# F.lrsT.Y}9 hxk=Mݺ]L,lWqbGw ~E]q}J(9j˱; k{!br>Xu:c@Կ*:jp0ޏb 0i ꐮ!A -6 'z ]vMӶ}6y9Ӭ=0&R^G~dl&AVȜhFPcz?o!}ZsǠ}l˼1-u]E8Z&OK QCr-;KC;hS'v(`Pݔ_9'K,Ɖ i `?}ޔ%7]M,Y' #O?Ym:ݲDiҸbV,lCBS:<qgw) *Ŝ:o,Z݀33fVA@dV~caL|IoP9#_{]EZ.fj&_5%9- nŊWW Er@9;5*a.7vjKC:.1Օ`zM*K2k"+Z*h>wN-W7<$gĞoicv7%|ß6%R],!N 5Hٖ܋8+'jr!H%dI| 5pxi1+rthpD[ypP- y* x4lP0f2!Z,| 4p5ɹ.Ib?RT3:~}@eKL k?h_YgPls&^Oꔢ8:~'#3؍YhB@!FV&2&n8dv΢~PXs C;?Gv uH›^kO,Ͱ.AY]!fdغE>v1 \8{gMy*~}$fWr4 dB"F xΦ<[Ro==|"IB 7_:0*V\hpP,.+:nǞ,%e֗Z^;Q9 t%`RC X#9p1/lCy aRkdXӁ7Ad?|_ʖ˦ڙ̻U:ZU^]ĒQd&LB5B~]V'K.ZwV[om "kཱིOS7H3ӱwe-9ɧP G^"7lYLLL";?\kN\)lM-=։Y7o+5҄]Si#TU,1@qMr~Q̈Pn4/rW"hjųrEXȒnz FiQh`0WbyQiPr<\lDj=em09 ea6c}:o5̾Ō^#zxٮySur6~ k Eo8L+?_f^L(e]y. >גb9C1GڮEx靷xLeawhc߮~c%@ pVhutRUɗ=0dcvʴFZ3 ;/&;skq4#m{Ã%F%T}{ؖN *J/5(K+!K30NϟPc\9Y?Hq)D}T댪Ym\|ء^-4{j܃갋0w\ h՜YIjd , 3kr8^{5*qqv,?w˭HѿX[ȡ54VW0iN}Lslhh3ĜX~.6hpQI(|xU[2FinSN-yth40]@]ٰr5p)brU0BdrzclC3:jy3,~*іY-b϶p0) ` &cJLppdRm'*UUƐ]w.d+&Ml_K0\? cJ\.QH'+7/>P`ʭ;'fLq^Y3j_gƿHHW_܎>0ذzS맖dya n5PyR7,;`Bbٻx 2a,7gSgrŶS?=V]u(_ϕ/w1pN/PFFĠ +$(|\+`mmXK{).C5Zɼ șĖBD]x˃ѿL$\XKd5dEou7Q/ "L6\Aj$yzA}l{\jnAP qCUv{"hS;6G5= aiYJ=F4ϜxnUiy?"CsfyɈtF~uU*Nj-DՁ2}=R k2XN[}Oai@Ѯ'{C=o=O BV׮)|+eBn#6D\AtAmU݇؞Vfh@c{I C8WiH$iW8;hT SkwBUi }8>gX 07+01?Jc[O'mF{"n||r,݆N_vOF% v!5%-<ؚ3,;{KoyL㣰.:;Q>CCё;X!L tOr~6(J!wSIg֡="-1H~fԯԞ*J(ͧX˥;ϙ cˏ$o5l4 m9YYB8b x|'I]*C)txLL*g_g(I+Oen]kSԉF隩 dhЉlzRvhK*բHV$HwVtmH{(ƈ;GpJVQB<`C[8Fn r(]!/N³X:d'18ܑ_` @>ԅ~;3<"!( =) _`6ۿl0)CjE3rtm4- uu)hBvgzJ$< i\rȚ5)锹<.z*vtG7%9s͖bLGw!kniȃX! 5d^]kRrA{D|..u7nh^\wet' B¢X<CÂ*[C>PLԇÜ*+!L9ghjEdB/L]ZRm +Jsj&UTčn#iMP̮zn-6}ٱ 7`Zk2Af -'0@ˆ?[vHht#IMEWoxmv#V])W3OSӚ_&64#i|USZP2U֮wpq{.ބIN-e,">`B[ptК铲iu &&W 5BB0'MF:(vYuKH*'FZ[݈B_cݟ"̵%cnYkM#u.ZvG&Up<ֿNXFh]=c]1 ,Cj_s4'9u5^(\HJ.,ad3!œ̏(:P(5!gkv CH}o9!.1]JъttTe"5Z򆞗]|0 ˩Qf}d+T'[mv'UfDb}J^w{}ra~VDȆ:|ҬW}H"f8YXe:G7L5ýڸ "2Hၺ4b+*V|9Ey 4_mc^#R0ƻ⣘. [PWzYKڠ[䙶b[d7jԪc5u| @0JGa-gΓWFO+aӄ+g&0"!)#ל_qi+.fIT Y\B.Rv(%= )}*I7aXipjދ 4 KsoQ0z¶[t rD _P\A,cWD̙O!paw;cy K+nS4钲v0[+QVqan{?33<;bb.Ɣ"LAg۲!v^ fЎ%;BjbZnf_'&uJi#\:G9J Jw m?-y@d]#PTclW ~|9ٔ} sZ4/*_2G]tr0i]@a-caYuuQore2Y {PJ),j 27Ք2>yXirf kFێ  nZ\܂7r)b0[4 ]l9\{wĄRq l9EX-Ȃzx+ӕ 0g j m #*:N16g)%Oq$aY 3flԩ7Rb`a40IWZ$g*&ɿدqM@"]?A;뀸id!|{RTy§$9U*<0UʺfsȶiwWuzHknQAv;_IsKsI@}.4|]; OnI&'$4 bD CJ&3lG6C;>qu~O ! _irX` CUѭ_ k3Wr4~S<qq_ q_YAUx8pNH?l(b&<=T=Rw@VS F mś㴕?HB !m% w଒et)gQ%z;5˳HJbob鱤;J H _ˆt Z:+>5܏0-+v?fr)H#!-3O"9\W%RlE [ldVɨH޺gk^$pK\7e?ӼXȤ`ృ3xvW3Mq&uFWuo'@[-`;*1ʜQwnpfd3Utpf|L/-ݨQxªc;kbD!9x^Vj!X x -qǝ`zl߫eDPgxdtoGWQ#)r? MܳgTn'n܆9nI֓t]%dnS;yWp3>"UlIBBzL}IFdr0$Pn|?\ܦw8HL_#>dcE.Uj!|µ`FtKֱJ/~UzlDpE*|ኸh`F0IFInwryP? n2qYbѩT9 I66D˧+cv mQP;?"#2iT*hJf) ^J00J=t<}&VE6͚/~WCUryY1`##p!E-5(FGm!U -`Ծ/h( smBt^BP E]K8/bQ̀؆⣯ d Hnb]x W҇m`;sJB-(j~T慄5Щ악!$JTڄ3o:~"(ÞלrX>O^.}J˯3dqQ3 K7\}{ҿҊzX9A:/6[=]qDqr`尚&: *Fd~E5?pGX{~YP5& "J;{^ܑ Q ?*eD%xB@B d6Ѝ:d% w$߹F?Pݓ M;ʧsc/h/x E^: ̭aIk8 ]\K ކ xXtNL=A(*;M܅cl~ G ow d=ת,xf\3*}^cԗ֭>!\0P!E`3&x'"3Λ03 OMrxzdWֳK*0qg;vUF-/\D8Y \PYC -K}E#2^gOdtsLs긃Su7F f|G<X猥WrQ{w{ fҙRXŸK:/pk]5-{ckJR QΟd]vgk]x$Z ({dǴ: $hY1O* nՕ5I31A+`˨S3^C=ql#%Ře}LfoMCrc`V*{qMGBġ~1JK5D66/hO3]Nq|Z. WB#N 1IýFה[SVg(V-C}qP[1haAmb|*ƚeYyѥɟO7 ${>qPpȟ1yiGiժVF箤֑|8VraAX+7KNq6{oez]mci2; cɍL-R0?z7/btt >0`Q8PĠ' j]a͍=wZ5o {+ ;1|o `I@C>;l?۪"$89G3/gl2fӕ{KRJfE*d/5-B68}j_o[F$ PM#zD F=fQ {lp0V Oy@jC۶rO_RMv`)Y1^"ҷP Fw痮U+ʔg&uي 1?Nd4(+gKڼcqTU(wɾ{RAQD VʐO)[Ej,#e>44~|D⽈8 aFxhR h9$.rx~.%,z\ iDXCiKhduu 8Η}%j?Wi65/wKrar"{R` ṼNNbÜʂ ]h-Rgysb^s?fm5Eh%ךݰ)r^oIwҖۮvؚr _>3o%`ZX aGɶϬ1 3Ȥ=¿*9Gȭz' cb{p]`IwѠj\jɲ*K@) nz4 v0ЖU(>.f(b.PS{U&Z5sb ึk+ɛ1\aCj08–G\ͮPef ϴ|65OSwNh_Oȏp`xe@~9iqգ4MHLߤK%k< P9J Q~^U{umkV Ja mR*v ' FxmElTӋNI?gR"`'n#{2@H=I;3<R DHY-cgN2*KNiƒUl):P@Pk 1}?1ZѪdvW*}L7B\Jd(0:&/Z'K{QrkeɪPԩ{kwm=Ge+C?:IS[mL7Oa򅏜GƆ&^@xQdqʦ՜beW9 ?޾Q?1_FKz^8NL4L؞{㳪+u=jY3G0͙ïVT,SVr"KFSYyCQɉ+_y`NS~w{h}[s_S(Z0e"b DH^MR#?)@TylJ6J/leX,G_k@ludQ\4w,!B$]ʣ3З<5r[ɍJ-"jA΀zT=NZq_a`wV62ء`qàzҡBosu݈kuC3kf+%}'N@1(gnQ5cz]ߤ Jug/y6dX>zͫDDp s_pEYm7p 4ƴBVK|XW'aAaz0 CnX| 'D0q phL58hqR {H8fOоfی! )!ߪiCn~^sP`!ℋU_y~c·T`"/%Xhq'벉9#L<>f4ɩ^:Z92%+KߦP]+_!GL[=^Pym:@^Wj{ ^q=ۆΚ,buD; '}16 W9>6A+f_nA /\#rN W.& ?PьO\dԻG~67 f*#DzX^Y'x ިKvbXI"n34fLH|N㰓*=_5f?6&;J8figs5 JF翰 E~)ZR2BT`̷@[ȓ. 2ŒK?'~"vDz@aׯv˰jr^+@ɼ/( x[wh_3#u-muD}ۚ6OO:)~P6*/mr>B3p 76e 'cCeFe_/FƉx qTNqlPC5~ip޼Xs"} ܵlVr "pŋwws{,Q+˵&EF3F$sƋv|/ϕsLJn !RtfDI5Oq\,~eN"B|h-} wfbgFaZɸf4kߥfH ."洂ݤ>sgnZ2' &ě}7ƁhcG (/nRO h$sE])M'7!3Q'l1 .-Vj ZW_u\͗+-=,eߌxƌ^wI #c0Ժg!VDкi]|9rP} 4r"z@ ՞f]Ks5SHƳ__AҢZ'k dE' ږ;zDq`Kv0 KBLFgcFd^]+U٠ WIQnwgM5_ NJ t05ѵ1J`M,@`D0^cG|L>C<ȡ\v)M&6ԁw뀟5[/1^>+&k6#6qeztSU,l2X!yȅϼ+3RHٴA3_ oZ*IX}xk*q*-1Ht\x^QxE@+C ssOk3MX%; ԥ(]\JYl/l2NMؾBuArFc>Tb h0ȩGh|H)- I[--AIf/v,*u.qb7U+]`CɁu6'\6 ipdhbf@ft]Y5kȚj_W'y#Dc] 1m0WF'3Sۇ 38a<kuSyӰcF?N|7*-M> R&w6}i$] l;26x^]Zڳ3ps=Fr}M8;~o1l:J$`BjsJ7wx_W̆?X/LvҪ~$ R6Dmw%Uj [oj.ᩘvLShp*9&&_!T>cBazj*H; ڦV.ڻxUyf/w՚P26F]G89'YcYCMR8j:@pwq,pY)S |DW}u>Uحa&}:cTI )¼qJKn$'GP.꬚4h&)fCEt\QA#LMA$rTILN0p3S uKrȘ(5kHwJisę97L~&ÙkO m, wCѳ%Tڳ62ПHZʈЋg|V5UBChwu[1di?S #ޠVGU? -[6졬[W4B/+q&Û&/AcT&e.tpqU5'LOYE`3-1T(I^x@,zdo"!20?&qVp$BgL+3-=%Zd%ՙX]IET-k6Tw˃rz>7T)'nPdnc_^os.Ga ̔Sep<  8{Y,(T CMC#-ʙآumPO%q6}7f=>K滿+>q&P'Ko9uߘ_ [K \!`RS90e 2e6Y@mXL`(G5V'paCxǞ]=,xuSe&&E^wWu޿۟~[ieEZY_a [gîMY SA 'fYp#ꍂr?PGwCh hm3_HP2iRn}u(ή#@mKښ9?^K,Mʓrb±o 4S:|EzcDvdy NkZ8^shݒ9V KLt&43Mk t(!iزۘt%SX ck0IޕYxI^DmO䴖(" \L7MrF8?%xNކ #GXn~rRL0D`P;{k[x;h?D m%8 d@ /N)4 ]׬;vdp3M/RL|&c5GUKT$K%I&&EG-F5"Su?bf~1x?ma,N뼝n>usP)$8P IfPkv]NAi,9q|^ʜL/llEOf:ORfʝkPA7zj&'?HMV]?5ZO7 ) 4WǶ;Wb0z A\B\Ne~:)ӏgTʙ"/ckکiY5C9m{ީS %Q8ƉgH$1j}PFگ")#t  =Iπ1?ʳ'ʪ|T1he$yY0܌蠈\"+i(FI0R%st'd>ސ:mB&uz21:Ov-4*xc܌Ea~:R&$Fl˿T{ f}^i<*p]>`++~t.Eg7:/@3PDtu9zSyu,G~o=hDOB2£5"&8BĻ1&C}3- % ǃLٰi1;؆辆85a!Hx'-HZ&j f΅{!? G/'WpCJ,n@L/HSA-8SnX 9Fzh4twsLAɇ3O8*@|_82\BWw$sS-;Ar͝rŰ WIo{k+gjFg/",̘>VIs45ؤĞ笊fPYDV=pR>Up\9Wfu<}/)=];wWݔtPlV,hqp7ҸCS:;(*JgMG{b >mXWa<\lQ7|wM@qESr^5H\zz$71$G ґ}v[,]M{\@Y/{dF"Q88# 5 5uhK3 O~jmmIRQ~Z$6׍D? }td*T bdx mvlrɄĔ*;J4wӝ=gn껭Wȗ< ^=ufu:Oi(iOu?#1KI 6y/kke7c8va 7:s F%{ٶ/sKwpwSr%Q,Q4-d;p5lGt-#dUҚJlU BX7xnǺ#t[E黏3:nj5U ~2dž>L[$@m!VlUdbI(*2@~~+T=MKq!4vs LT&& <"{a΍y kBAzw`[X?7xĿ"kqD0 >s;"-e[z?gb0`8/}0VdE9wha`O6Ӫ#[tzh" Ȭ ~-\5bf?wgc󏋨=lFMoŎ 3~4.d ƍA.lϠdbi9 ;:9C>NJ9#B_OUOA 7Jc* [_[03uHU u2kJ+=SúgEzkU;&31jziC:,BAy~zy Y||ƀO+z9o:JhO"!7^"5<`CF MgSc`e7ɪ߲9#GG?>ΰqz>sih_I[8񲱻AwV~YiZ40TQ@%A"RE/:u\̲D~;#LT3Γo Ȟ "m^! lKp0aW3ԯ }\!n4du+E)/D[tVaS&$C=7'+.>|,\c 1<~LqjdU0C162mO= iwAMab8dx4~tm`ki-mךKERuOLLlwkpYEO>RVgS놵 4,P,t7$xҰ=4K΂Wo ΅EQR ABUOف]MMgpl$!m21*酦uIdUTW8hBQ~ Y:-RI|0K3/B֔qOeKBT .xn:pшg*Td' bv\{aΊO#A*sᵲ|X̑G~gxAe:#\`Q.w}9:޸v@ ~rja$`}GɄ7mȓi'ƚd%'ӆ=tc2 V/8Bkþ!Z*svǎj&?yYE7?V$[Oe; %iDMvG-3UU. B }B8uBi<(mgXvPZ, _RȂvOr/6ד }aLi )p LF5 K뵤8mv˨/L-+iN/#ϟMg殷hwD+U!4&5: ;dD ^X9_ )z+@Ax.fGq&|īԞXOչm)P2 Ԡ+&o1!*yF_pvҺ t'sŤ,MSH(SFj˔܅5tg|2.UA\ֆfdKN2Br2m7O aZcљdoflNz/& !yPƅq쌟 qK.6R{-vB%p[,KPe-bh8Ce[UHF1R/3 ՜o'gW>-0 o8@eAb׾НwJ>ƴ7Ul7u&k6';[MpRqx+xm/dE9|iPۏ??UbIw``;IrRGOS'c^"2)ƍ}<i(!xR(1[ה|SUuz?!/ pCDm3(\D4~'ˡoCuyL15rvc-%x n4exqvTj[r63 v 7:ױuu&icwN%=vMFz3R>Y1 >1p Ư|W--\I=vL1ߦyDq K?{d,P K^mןvsUܣ qEH _]Q0En 2y[*s[ oxIjg_muXvs6# jhVlfM!.LT\zG|v {I}7Da뜒u.j^PkBkFZ18T#k97+U*[ u(SscAڥ$ʬJϛMv!n.fk"}sLVXϟh3DG%F.'v8JmOk9I V#kU{d'/DN,p; ^u"jV mi#nL'ISxrRU*([ rh#7d т"M#/cĹWxX'Ǐŝ^˞$uCeڼi{Af \7>Ռ̠~'´2Y7t荖!O;Rg榡xR!ܜ|sqs b0hbfr+N֌$A8Mh]'ŽJU/{bP 5fasS.Ui%4j]6[^N0}}&O^u6:?8;yxɒ +H6qܜ棞G I_alx*":7i͔.<tm\fÃONU2$e9 ] ->XJx+>i.8O3uʽ[`^LהupSa@sZW_|Fk!Q Qg>9y˵E]߆h'1lnDLֲ (~urv9i%F@ )ߤg2v2.DZuNT,4;9@ _oAcAl]HRΉ[|;Ir |kuJ)Bۍ͚9lq,]9sG0_X万 )Uo忖kwqF @s2v;gkK_ ^s%>kJwi ]VH.aHfr,ԅ9ǎ]D6o&?cxVf)|TNt _~5x ѺG Oi!\.SOXp'2!Wd|2ޯ9X: _# [\}x8c߄1A*E}XËa^.׍MWW*/A'DUtPQׇYmg+`đ8T}gt/릩y &Hu>3d͞;^HE!/&u7c u MUpi 1C%-R'GPZA"P*?wV|DJC h}b<4fV6y`0^Y\?[g-cJFP׉uixeu>T/!iQ1of%H=EJhYˇq)c !qDhP5g|22KnC5s %HDPw '?#k u,PoCd`'lő)vK8=@۷Bnw4{,A;٬yY5 , ,"U+؆ٛ ',0i{(Wc3_#<@Ɋߚűz,Xs:X6y:842)5,&ڮoRõx-kق*NS61kLDX4ziͳKs#H5Sp|^U1#j2bf@KHh`)Qmfm$lq?*XIO 8ɀk)JvDWJY=,{Νi`{5}Ի Lqbޝ 43{΁ XoIl]U+jVndG@UĆK܇eoЉBuVc̭fli+.OeF]v ٯKdeՁWKm)0Y!IC~#u5ʋ`#G aS:e"ڨ\i*${J!6j֛g%hJry|a{n[OM$8k"$nS_SWhԗ U4ZIAD\+Vp #1[)j7+Er=v^#j]g1j9T51S4K:"(6}btDb8jp_Bw3aZOQُ!k9N"f2q7h/E;K0g-Xa7B775{}R~$[X }Fus߰+ٻIJM'iL{'>H r+ re9џ34%UFX|6LT?W/i*EaxRUL  bl47\'D6_MNǪS]ܼk!f^ z8tعu`ip8K8yM@\~3/pUKeY0fW|U_ܘmO 0%8b=׬ɡ|5jV7cNL]^Tɕh_1: !}#mi PӄxuhW6KET[ٔ}nGWJ`EKxg뼪PE /$G9Np)MOpt-*Kkdݺ6[R{6CLlPo\J-.۵#-Q jfa7A 3B1UE+>'1UKAOJ~Gu]q^Ս]fWtxu>N?Aj$]mD>;xBZ1SYmF.. "ۇ19D5L/(bŭo 7m,`_Ot-]~݃M~Md mLs"-gIu#NhsU==v&|?wq [; )lJw.Fnqf)Nc;hIJ >?kP[zȟ&W.HrX>=6]N|T!j᠉'];DpKP꼱u!7v>\mH$<5*{8<ä]"rZHYɂS:x/Dw)&CXk@NqRC F!JxMRLN%K/"YE9D5OZjB%sؘe[ID;-5%U.*+2v9ĺ9x.vB3Uc C\e^ C6y 0u2uYL$k}ܲeҞIJykQ{O7pN3J{WP(le5&7" ?.8skI >v{߸/s:E.E]mbkxͯ0s?<^P{1||vQ3y\^U\s| sC F0ޗNo% r"7"%m?X4aDjWH;j[{`abGLc GW dYIvk&ۨX4j /GqI-a%fU,{- &+'7뺉K=q ǵ"GZH;U>oftK&aI@nAD A )2ES|@b9-*ޫb\/ 1$gP9.}쯎s:V. b ~J&J\c +9 4Qk"|Mv%X]yf2x QQ+` {? -Ĝq0`a{ӫ$kC4:B,YEDaE6@?惽7A˰7/E@0"#XG\ijٷ{ÏP , 9">#a32y^K zK HO.Sp}[kwໜ!|IVz؃sX0J$:ck'p[3?TުG> noe$ZXo u5w_(bAa@/3':`of ; }֧XF>(>hXS#ߨFvB/;(X:Nq;i=,]T@n5tw}E+%4B2DSjB132+E O,}v6}Ǔ3P/Z階kkY&iZ([8"sv"3fkyXAΰۧ6h< K(JkUlqs$> sʡEwo5dc7GM!mmzeo!ަ ]¾ۃ박_P@٧+rq:b>3yX*4fXZo~\v 0YȈ+S=> 4>7KIDD$  yzq'w^K:cti].MQ.5˕?0"p=5Ck*;Ak/xaS!A#HqS.b@'{&U=xYmDҐ!gRڋF//gq =7i^!?f9<4<>.TW5M.@+7ĠlբW/\[seGMawC{vc}}Bt2C,y' q7{x 4K@8W EbDt,KEWbo˜0N1sGTm^ļwE亭Bjno+KnB,=䦽kP-x ̨gnqn\Wwv']y콦NH˾X<$lM_ݽըƒMޥq{~(ͧC0M4vQw G~MD=esڊ$uN!0fA-)w+gR6&ޢo=>%"Aeb2L 5)9PtD q=S0Т J .!/Ѳ6x2)mxWBay؛lN-[vӔ/3J-(BWuTeem TOߠ>Vwujd[ԦFlNz7!X,?W7ʾT2` ٦Č9PŹgWwX~qZwQbWRaDcS~)lё3U%Jf+]RW T U NKs?le.t쇪՘Y]ۏI竅M~})<1AWHEZ||hau90i& 5S Z['lv͘qkey \vvRzmm1@}އ<;4/3?8_w'H,b9]hHtL,4 jrQ\ k銙&3| W;Vr5têtín_3ZC`@נ$(q"1u,z`CZ$&RæSq >x~Z #1"7h*A;{x yTHyzlQ7C'rʛo v!.jT+Zb*zTGo\ϭ # |8 !+1,6'Q:1#IAV(ٙ5(Ina}+Z\:a ^zuEg10:jYFs#nymD ,hdJ?}-?˰I0Wо򱡑EwVӬ\)?1~6Ouyml+~AAOR0% ߎP׫BqB\w@ Z]_$ò$r* ZJ=y'IasY AXy(E=vgsݭaڨo ͻ <&BmX>ZN˛>7\kMCf*C]lzմڄCPWiV"\Q0³: p'=p%\ z̛U1k4=]Kor7Dʩ,{DLG0"1X?'~=$+7!T'n9q|_>C \}_f7qͽ!5AB$X{dƓ?sLH*M)VsѴCxwewo'Pg; A̮7~U':,.}j)t*`D˜ΟKS1:QxBCFk5q:扫J!wdBkCiC v;qbQՖW4W&vE_Sc25H`lP'Zn3.N FTCQcq<->帘Z 2վLh(5@WoF-9|g!Hb%əᵬl"@ȫ2|, XL$7 (lUj#kq@wOZ.>T| >"M$dS/ {-8j{L1xqOz.URX8$aoP>(QSq'qSǚ  T 0mꏩ7PvYn#)9jM__MmL^u :S|:H6 v&d$π*T! N scXu! '`uytɼrXz> pqo1K5j}{抐G@VԴunϸ]W]?74ahM]<{k.di~=^C@7ԅj?XaTU8YAKq1utEٷoc7BN:F)쇉W/uu>lR h !iGnϹxZs SS^"c"(x͎i᢬vo3ㆧi2 UEJ8K?0jʚ5;mhJ-K|V$RL%%o]۔v,,;&I\Q]cLJ|5T~xౙ->eJ\Vd_hu<6E0"'zovIM>r06k%?F (-Kai(AIȦuZd}u=ok0D+F>B,lsMY`)a+1Rx|!뮵oUW3T4* y8u8Kvz:3dF@ lhmލMb4qf93`==|=wXI֘`N@AgMu^ָv\n]"I$j4\d鉧o/-J~?wC()h^[eNZO-$IA/Bv 7BIG?FD: [7K-O|C2,1'!ITʠyV3\ܦk;OkZNFmަ8f *Z>pS2p4]TIQ◳d+poKyx D9Xɿ<`\;.j`D_*5EZ˻I4REs8i$p'[۠E$`>ݐ8:~T}}b܀, G%sI7C^ f܍?kix8FHIWf ִ mhE#0"vw>%FA:쩣w#+s|ȨI9rF؟`U}ivfJ/b'ڔgXeK J vx}n!m2Ѓ{G*Mb@)h}\ '.O_i-c/62 A_VbFwt >W+Tׁ!]ʊ&/6` F{lnş~N=+Dᢆ'ȼH]"WF zQ,'i/ƌL껫 RU2[b%K:xTx;{9eovQ::?IfQhb|{{Rz׽.I1,6&މ2[O@ͳ\HekK9r(.C37SY?Z"BX5H3Wv@bSD _; 5+rgs~lJp8[WLn D*5]d+̉4D)f 7iC/<%I C}OmiDTЏ!K7$~SFDHD<٩QN)ll.{b"*VWgCLze],x\9o0Jc:)bLPgNѡԅPtdǼZM"0vvbzY+,\$w;Π!#``:RA5h!7]`]#ݒ7t}<5:ĎC$%slgU5̥YG7"lJ;>s348CW'' Dpg_ށz$ʐ|}X`ekV{iϺ'pYMșu*5k5dhIcN"a^ p\ kФ@5jipT2d>2}38je׽r4 j.ӠG*eګ:{ȶr9ǜ -a5Qa>JE9-B n4ldx<=U06.'aKbaeTfM |Y`X@]ӻ^l'-Vkjǚ *2禢՘=ꅕ;g rVۼ_* pEwv>ԡR1=$&޿gTg O[iylbh! 35S!"T:mt* \1s9ڥ56W~gVB 2J7] pE@Oδɕj XoMEΨ!nɪ)Mb]jb?ǒ|wB&ȋ ?ˑM5p!O :QKTuGLO?s`{tu+8JAJZBizf°/Fq[CoC W܋.fR+l8N{_%HO4\zlA#4/ӱ>I@=K_)lpc1q]FTH80nZlth!?Pn3*'|w~pad%ONRJOM-;Z8-:˛5v,K({FEt4XV}IkUYştyCj΂2"e2۾hQ!hfF\|".#JVw'G cUdV&#yqv>kYIԇLv#Zu{k%'8%ɒ/`m7׭c4>,"3@ cmu>J;(ǾT:F& ^\Cb*[S{Ai驜MBLAsLWA<^TU  t꿆gje:','˅2o|zdoJ;a?5VVBNzNV}Aw劜9q:S טZWh i'tBeLȬ{.hF`79 `x̠}3h'l{OӬVNDm oy-p[LN*.4d"FLBe?A3׺LQU fd\Ch& ;EG{_Ƃ\smܶ3i[fՃ:n>=1O%K-" NIئʥtv'4 IӦVGT؉M9x|A,ҋⱧZoE)(O:⍁5B%sl0g]}ӧDTmp8B*|V6al"!D4-6TC$FiҰZ/^a_yC+#XŒϩ-5Rt+Cb6׀7XsIŋ)+ qhʷ¿ބf6f W1ql'95+ 8`5>c3}2D2L+S a@﹛P8LPahQ"}n S<9qtud0RF)ZM![$J+K"@CjԲ&%) ͡-Z%3/~&21u0bP~ WQJ<;8l!]⪳[H5#ZɌsi914f"qqs],\maKo07!5Ps2Gy['nt~j0W JkN0&9F8\0FRxkb Ww]V=a}5x5Z]YtLf\^'}]atqe7'Sz rzQ`grTmBT|ܝk}[mO_ +zg<,&+!ԌYDb wHЕޘ_88U7.9cr߉2D\__0?v9 2*cӎ9а0-q!ِoU٠}p_)/S ^?498fҁsh ǃtWa?_oM g7;|2BXY{@K~ * |܇1*a_*3DJm3ƮaqCirESεg2o1螱;i!Uf+lWג,OYHeOg]yX{v\ϟPb}JPv3G +vG=CNls ?xA¼kUH~P| ""٢נ{zlM7@%luԿ̽& l`՜|R=8&>tMj]0k`` 3Dznc*ԟg zC[;@y^oOTf,lc}h~j4'KBkjB;p?]wʰ6_ Pd]ڼ5Y{_1Θ1K.CW^ďdǘ dXnm2Loyj=pXR /O=4MOQ~ѽ>J !{=(yy+Cj*ཏܬ^3cizOi1 1Q)NݕX\N Cc!>+FRYyx}{q<걤\hV[i2g٦nF@dR~O{{.83NCx07,bÕS Pl{#Z,=WOɠ' xX"{8=Cy SDzV> ~"M^jMt-'_ml_]3#turO6&vĶݒvZEy`R]'h1u4n?2!KHo`1l`NYbCq hDzYdj_9_#4XCO#u5mYB6 9QҫtA5zkdIJJϢ9{S Z? (zL̥CȎ\ HvıБٟ4k"YWVbIP.j^gb~J1Iڸ|UʀRե'?$%)놼DƑlwU aM:ƾyPMQ>* QFBzRݝS'^ܾp/eB3- LTv!W3?}SHb^%Zʛû^}~fg%)y3􇕞' Dꈟ[Э mgvbq1 Fi0},t=Lhr Y0izFa8T6 ܔW[$ɶ9n΄,qt| Gt?)SUР8<h:9$FKo ApRњAP .fQ8Ms"oe zw[5دB9B8;aFDzgz-D{ &򬋴C0?#r<$f{T` װ! iPP7"zQfo6j CR?UV\%h&4y4󇆓*v\mN$> {aJpˣUCD.bh:=\?oJ)HJNK." \-1B !2rӍM*늩qxc:]9~cԩZFWcVFxPIZ:~؃۶UΊf?ywL`n Q-Cs pFl]잝b7/Έ XRfChAY(%t]{rHrGQA=Ō }/V1BxdӏT[RTˡ8d";nziV۸8rp5QyN(?|b>a +7|5"'tz1٭DET}F+T=3Jtٷ$GXn!_2Qn:-U\j5;50،>LYxl:W.X(O?yfpQ)Fp9 h4y/; r$c837Fia:suaaB=o]s_:UIi^teEVZ&WPxzmg3ىC(Y5?@ {X4)l fq5ORLwj= o%na.~fjJuG*&*R5QɄ1VX @ZmRgOeDcK!B'Iq%zx(b wst#) 8,KSLvIRp&j@) S,o{uMwʼrn9Y?%Y+&6ikSOHvnӵA7<{q1Cm2qdR~8:ͅ"!? L0Hrt3,/%o>}wT%pb6XRHݛV#֑Kn>jLsJ-9_Uan {GWZ.G}v-"Deהf]r{Z S#?P"1ǿ~gqO1s+M3s?;Yq]0s;pLb-Z~aqjcTUf*XާTiM̖5|ow-6YJ ? +kT\e-%dY'.1_}獽=0 rX+*;`+zv]zap RG+, t1=:!mEJ` o4h.DDKEukOEڪw8_%oKӔpYOS?BTb Rgwg{9O6z8tv| 9G5ـbi&%:(._BU_(;LΗ/+2:ӒСX϶CzYF5{.Y$ \ɤP$Q#7fJSHԵ}" Ƃ=$G96&L"/4Y ^8,uVCkiPzȧ\V5^ uRdd`5< ŘMუQM5E~is*?Kl~&aXxU8n#qBOPѾ5wӽԊ0];xO7`˲хvR?ʹKhCeYLوbrq~xes=m;EHs:eƚ]Ep^hi?z  *1[+H?FkD&g-(D! ~$97 BBFwhWjQDr;2Scex"-Bx=@5k#h%`!Hto\-z&ȭ~CȅonkSljЕɴ0HV$xE_d_]dU[*beHͥڲjz ^G^]&țNx6eVx`SFG _`iN鱥%9yTNtNH^"˗\~`ɂ폺qtQo# /jnNrN!lO0dl]< 4heX,qAW{}zk[K8]fhD=HRd2ظ5ț4_o|uL0R%>15&06p5 E51G9S*e!~=sׄ{wx[-p涞-Qo@izmu܍f=#<8af!+di挐ߎZWnW J!Ko @G2):wLrR|liǻ1KMDE`g2>wGid}B )Ĵd,=KJХ6R-X#u]}܃/( }εj(~ x}J4z_ySabJp~Dewih Vcoj&h6|83EjG\»]#&l;IFFLOPQ jKw $o)鄘/CΟBD7ڒgȭ3_h3ZtiTAhk9WȻ?Wo"Hs Be j`@|e+Y1[|khsh!zy BEq)d!LVr(Ȟ `j*fn([#aBv,E4E.pCئ{$ZKUyܰ5t@v_#m##i*X![9 zCzلUcT~u`6&bTלCnoO^W!B͵;+/}^~ O_Mv0ׂ)Z#$B}RH!^/7X^\*h1P#H&flW_MjՐ e?et*^0;8BH:EL2j-$A.ߤav bڟ\d(>du,Ya첚q'aKr[Yh,?l ĘDbK0?c};,_yڊ(,aGRֳ>ˤ7+WOrM~[$5%Qw{ ) džŚ_]Q;Κm6EubI,b0y˪o*󛨉t Cdc,QDrns#[Og$):FEҨmj=4͵@j2XcgY4|}0|~*ڵ1Y.~"HZUlt[(T 2~ӽ16T8s xb-hrۃJ8=D)Wݪ'٪[C]y.E/6pCo -пDt*šYm]K3 Wp E Ԃ5I3-IcE@6B-&QQr ߨE:\IC9^fr5/hA=J|Э-~6j,Ga4Cx,3 kQ9zvP$x8y؊6N `M=',e^_% ^hWgLLFS[X\d7t*n8_z9B`Mm2xJwq;bܘqc_m'5eJ>@Qx<224Zcsx 9kԛ%Օ5F_m k}._VS_ /}vF8{|^u0֌ KaF1zW GI`wP?Ѵh n:=6tqOz8BÉnqw*޴l0ܦx-XD]Ӧ׃*LJQ"axh 1vMf 2%vĶ=- Y@kl!bQ2p 甑W2Mm2c.gzJ0ģ(GiD]C /8GV[` >aԋZ/,8 6 +|k–{n/ \(KthtCާ<͜$AY:\;iBzK:9wF=2M oor-A3ϦdƌFc8k>0[<ϳ}=زaU}v,:ݜ6` 9gfV9ĵR"VVFooZSnlV++鮴Ga&کAF#_;Q\Z?n$A]4<<gAG **J"vPc <0ɖT!0p8l_}W 8|j1L-#^u6Xd9h^l4v`-c+>qФK<1 PvƫhO\LOCHРej;tN+.W#&SmPJ0oSp'V{XwP^fn e t'E44b3|sAnCCVL6bnJ(fk "TH2H,b>w~[>O/#BV $NwV 2Wrv?) ةW3|gz N*|W-rUj3|'z1o$@~Uq[k rqYj?ϤdO+ Y/C,S J[8-:'4SY5zdz+o5HCu#=2ƕQ4 0I.A V*c|"Wva~݅.!wEQ6Xc@J@pLB4m؞/ʤ{ e&96> JIuz6FZE3]zpI\Y ~ԣIG} t T,4 r()Xm[x) xz$J? ,>Cz31`vtk%qtѴ}lq lB(USL ۥk"єc=dv6!k' |Վ/ihocVH['N}sufH$@Y>%lg7l ϶.h{~;+# 6oI,w v"XeÍAe?a'z=\]:G,q/8"^ KV =M91ݔ}Z{22ŃJ?H!PcXR>NGzz] `=ki94=/.O]#ĿsΦt `/5PJ+64?~k]/*|beN“o`=s.GжC,g l Z^{IC땙 8 &ίefU[+-o3sp1!|ervQ2|s+>\\~5v*8~63o/琕wE{Fp$S WMslI[U(\܂ެbShl]Y3eGBPSM.|`5g- ~ȔeEgʻ-z|0I.d%|f#.DQⓖ%:ܰ,PUdǥ ?B荞빰i U uӗ ^+eu![d%?>6m_@H8om1ajIW&녰QH(u/'@jjǿȔY_& #>2]y<.2ۖ~)ŬK]}A} s e)v7}dž3ANt {>ë2-ˌoX0m \390ڱhZBBGQED+qyK]kVskzz/93-?<%P|)wDWȸKJ!q)Q j͚9F|m~Wg1;-.F}4KpCahvpitIEM@C??0: @||׮eHS/7Tʋ<);Wa ÉG=`5i xf"^CwtmpW<{=>Wɰf)h60)vi yVR{ P .ҹ>)IVhyǤpnM:5XJgXǩ.lI}fdq14z!Rħ,̫'Q^ޮn&T`iv~_"/bX7 IFX;ڵgqZ!`qZ:N1K'!|DSn@A+kS61bΟ 6;kdzh[\,S*/ exxs5B$4Y )H+ѳȆAs[؄Yh2~XSiB/w_3W9}}O\I|o[GoD?K8"40-yQYSD-E3^?)f=߼%^?0?# 9씽 $|3dG{cx*~>ie=a5ݞ[zFP|HxxoUm<}Tw* ;?:@dC90 yj.PiY~42F ʈP=N]f/ӝjT%_D{}c DMWFuV_TMOj_gK<-*2epӽ9rQ PW)ǥrAI2H))B$>`(QbP=Kk=fx^NㅋBȷ}~eǚg8G+Os.%c3qå!y <O n4ys[G68DX1- *hJ!0ח@:̥9ydY)*n̽Oi[3eBy5?mcFV&bop'T ϖ=3?ba6T̲nKͅFb<` j,M{K-f9yJh@Ѿ|P gY !waŖywg}4oPKr9B`+n~Z!> ^>IB"[d)╅G! _wF||b+BbL[G:5iT4piûZtw`}f;g Mq[ ;x9ϰPL>-S΃d=܄KK *] PW=C/CxfRŭF?> >6@T~.eL w/Orh~O9x=ݔ|&KB<$ T/{r8Bti7H%h9 QP 4E1p]qiwszD _qS&  u,7g>X6w\tNklKܲJw\o F qa[?{Cnks!nCIsV*a%ۇ}jcnl=h[!y ʔ\bkZ۩VRx#y!$yTMipW;B M JZգ}~'*;%X%IQ1ꎔV徕/,XI'咬6-{aH'LN ;u~Ln uoEH8Q1hؕ/l8[u<ڗ@C(] DSy1R+C>P\2󠫢)GӴU; %~ܱ=tT%a7=U$JIB\0 "q"! uڦ#u8;7\,'AxO{NW ~!HEwN.gi1r&0]P f=D/<[' F57W^~Y:Jzyg}}d*pº. 67@h*B}sIl>tD3"/M3Y!zF 47G dFL̆5hCܹC{uu)<<R4cRJ^1/{ۓR:MUa?`GШ.ZDg#/`'WΒk,*H8zp<!"k0S;u&V,M%l|\)?[j{fy_\A%dL`?-j~D7Ws ɗq$NW}x}^HlHA}( N!EJU2K 5ԍGGMB*]wT+ YL?3(96Ciozhɬ$ptA sw '+D}Lt@wkxkU8)ONƗ%莟-}8O)fݏeoi:Hdf`P!]fog5X@= tdtWrH$zG@Y;GD.:gzm Wau`dcA#eZp͓ʷ0T* }+c9HLhkB~ŸC6}&v<'aCq1&0V%Zjh9%aߓ|s\bC+ q&-Ajq}R@\ [G! #;pJLCiU6E7g k F;?i.i88Q6B!ƛ3qK|-u]Fw?$48NB͛<"|*S Q7N2$*$3[NRhP8SzP!3.ps-wdr܃'ImWtI>dJp;W wj>gX,inQbAnHÝT du7TkcYe3~7L뼶{ÑaC*\tp7x[$,n||+n`> -wM^uB{x[hT]$彖>w)#t4MK6] <0 ;Lp's [s}7!wi顑ًA;sV*yjthgp#v`?SGPa)rvo҂H{yUEd/M~o0 ,obg; `T~|[%(yUO[2LfQ II4C %~h5bd܇dآvQŜvja8> EDeB]U,de o[S <{6{g/1ԸDJM{7a[5WTq ]m`/ttqUyV*XIu.Q|Z}`PzLPd%=S9q$@W\^ڱ[3&% kߴMsD jY;>34i'~zsdP\R-~Ų3`~28AgIA3R_-;y`ާ F=:zF[/ُibMD_HaCC?e =44_9eZl$Ά6nfԼ/귈`)ʎX2`cUL|={gnly1 ؝BG{zD+% zi\~酠?c8ݜPh5fr64!ORcA *NE?De>ypХ),D{T٩Ytop Du% ېʹ9 sx%ͣbh8s=eg gq,6%:4hYvhv?|݈5(RU] y" ޥ$n3/Y~Xk֙NːN\D:0a/vR<}p^zަoBqo= \IU7RdzRT%n(!/n?$5IHn?:;#u!#J>Nں (clw@̺b-(Z:'2R= ⚝t~\TQ|HDYHv(#$qjwceCup 9*( {T k[Zd.SCs~v.ߠ<oHRmOn1ޏH~*$IX* 8 :ƳY\[d9! ?ZlNK_XF.ktSVp$|,eC>pq+w4_S3MY'p~W{ڕ~o ʠLzcuw<,,qK ȑB8jQڈ0.'_%%7\ۛ[-nUk_dj/hX1u ;_psšlJu*΃E:UuLh.4-^~j''6h*t5pN+w1ۜF*GJ4a kD:"a,<(Lc[ {jFj[鍚CeKf "jXRvԗDH | @*vL bD?jTTMZl|GH>%~F:ȧRۆV'v-G2Mi043c<+bDq.u?d E ~"Żӭ +5[_ eY=q֙8O|5p=c 簶PeDE Xbc5!]$r+?{]as[ho2n0ҪU@hDZGa'?IZx:CيK#JS5d Ywp2MP1<7}RLF6cΜ&vZ8ǃ==QGuw7뉤¾Š^0F*0FkR@ˠWEkU8# E_# O a.mx'  t*1B6,)I.)T`7O9g& xL138 R;!%[5¤ʎiKnF~~o lY2 A<!5x Qvz:O5}LduO# u/Ѻu"~R:AfVgsFKAz~u_k5tPU|} 5BB!z{Ђ3iqg{)%Tu]v:g?UxZ,'|E-GggtݟhTb `]'jI H_qE%VW`yfSgu^( jH&w+Uf^+@ Z^G',J*HgAVٰU{P1(GkZ0!@}+bVdĕH;݋No=7@uvkE'>[E=}瀛 2(ީF!!k*^sc3o~{+QߊdDZ3Wv LH@驘PIm R`F|/nJ{R-H ] PKT{I`r@8hu_^ pq*H@IvbhEV񂹟Q,և7 ^e7&pE֛ &`JP:u#w&N&4zF}t{jh)k, #@7{RV bVUZHd= 5Į1NFČ Pc$!7jW*@ oDB 3l)ĩ+(XA[ߟWq m1C~uF)Ft?zY9?|kzz젥v:JU۷7`Wu,@ȗ\JQZYk<ݐaK:|6ڈ~^xdgdB=?6D]c7/Πq[/@3~$ZuS9)!NL~f}'_)z}A@q5~rA{.%VqDIFrClF+fdx)`ߕK?Zc2eӿ+tFA?2d&99*%']=G>鶚.?\:r+8Hmޖs%3?-W?tQv;X:Θa`Bcdջ& .ѣ(mg`EY{; Y@<>^>zx슮MCD _]U}/xq"@I;dZJ'RZ_F- 6z8fLbF7m혅};%Yb[]1o_>h)aoIv4=)[ 7=,>=ϸRǶs9PO^n]r-X[@6?OѸ_עyE(&tTj XRfpݮaZ9 fE ql~MD?x!H&CJ |,Ux2_ol iSDhlj/%B2B〻ΖQm 63eDG:^|78HnlJSTiѕp'ʜ1ع&8UqՓ +8² m;,kM4M@ N˽\j7WDT?.aDוv~5p|P07nzċ&5~Sa"5 S蝤/)5[DIY)5"եֆ=o%t5Xϙ `ŞZ t503΁LCsK(T|'%ϯE6Pe%5a-9gR5*.uAIے!s! PneSSC"U~e>{w5{qkßfvW¶wX&N"/AzJ{ h_0]E%̤Jì$+ui 9kxrZ#X*j''YQ^ ,|+ЊJI٘4N:&?WnPK+أU5j+gEEȅUZ)N4Io3Oih?ٗU@/ϊi2 E{Aku]VrH?r/ҭDvZJµgLxM4^ 6%I F+rȰ2ibZ>L[ @ẃ7j>%(FzMwm'P@Q2(ָ7{Ktb1tUrb,$Ks0큽(]ne4(¶!H$MCksi5(ټ%aI,!b^#*fQVRAȎߣ7á:^8ױftYLڇI#?8 Y*zԧ E` n!i74h٦[!cutLN:ɺ$ۙ+_f`[Bs JWj{ Er (kU`,b_(oen0ۨH gg_ S=lV)>C<'EWT#(T"7=2t@:O eEee">,Z&NJWu& C3sz3<bob+>rHWkVH>8ϊ7)Ih_R9[?: &f.][c{ i#J#UEX󅀺jd%[C2A˦ ' =t> 3s DZ;&a1C®civtwVFP8Mt;>ct}Pw:ߙ< <@PHs7(᭟ꈃF6*DMG& k- _f{UC!XY9g)B}*,{C} s]qngj#e/F7|?f!Aع[ 1' xE/ܩۮ!9vԘOЦ3.ޡ4E[ 7\bBnEL2KS_`^`һ'uWK]3viWkJqaN |ޕCЉwBBufAbg{n+jd,[iH,ފ(H)\qV͆z;%efwʡE] KQu>Zk>(|%9|ݙ1Ò!@MkZ# hڦpĈ"U ؆ ]өO)Do%*D9.es}a1+QsZl Q[fh#@3bBA9PTxY-`iXYr<[oɢUy@ ԕs#ҌwIIRХj[ɄѤI-,a/=83LKr0BτOԪ?N'5 G5K{vhWWY>JZkeB[46UZNPxHVo%( /;8.4 xr>wc H I{+ɮc1M&U}:UOKebq%>Vӥ8I8if?]rUjZUj<8/CCȎj(#]-su8/ m\5I4uvCp|G-Te#ʾ?mD*}NT4ĂLWSqS Br qb+4]ܓ?rY^Bzj [l$!4AjB.q5m{ΦC S~Cf hm6x'T'XtbB1J@Xe?1 =Ic/i-n;i̭I[:vrBdwPË.LG?-wH(-V܌NaO}akHb~9MYpD/QH O9Ӛ4VozZ:?s2nS(buB"Y 1x6%<Qi;Sm0d5wا LO/\0_䝲(M{5) J\=Oas#N`Pvs:0#>p-*9(ui9|g= maP2Ջ-FXa[ ,x׬6D|ʆ=s-ldj DS"#$Ցq(bZ* 1r&Y-/ݙh#ۊo8vo5L鑦8҈% q\ [h1(OƏ#21@8[[F^c=h-ݫX0';{< 8e{a;2KQEL[ާDJP$A'Qhanpsb'#s_7YCn-SO's *zQnsܺɲ'5~L% .J7%9{IE=ZȥW#e`:./ 텑MS_VuXئ(]=d[ˍ89HH٢G͟‹L^.ۀ-}?:f/39n:({dl? AS'W:H/ Gak? g8䜶`.=rh݁P.D,PWppW i "+$:sd.=RYͨ؄ u]pz7<HUmzg?fd MB܌Fo ~7:K`' REݸO7;Ub N:$#A홡st"Q>{ nP; 3Ƭ\H!uߓXtiEp,+*w43PJ_!Als~h]n{/5?g˫ǫpGHcl >(!S:n|ޟ֍ ƙb)*,lOjc1 K-84@k1h 2%rmO hq?foB'*;峜g{%'XhntH-\{YV'#Hf?"@qcy,63SFȫUGn{CEwBN'l d"BKbd+2Yy`C} et_Jşݣ}OV(maϑw)!$q’a@ɘ[Q6YtӳgDj`[{-b cJ!I IQXr0Y6KQ+ ' / v\*J |Xc(kO,,V0=<Ɇ PqM|H~%F~Kk9v(o{ z+9@꽫 ;ۇ8NvlA`2.;ϱxֱCݿNBr Ԑє٨rOuR&ɐ%m ġ8PVsNMSr*5x1M#mzfǕ2VmScϤܟaH$#hX%r_ܢ_&zs7y%u!VNLQ7s FCOvN!9 Q "3m;֕("9@eoaպ,\ `Pf7J`JiXul[L%YtNө)@du1[r_aHwAA+Je9w]w^JYYamr'TLphLm'U bήGnL01X%v}Ã~0G(Wȼ+D M70 c<6!_'k[h|Fk0v r:JBl_fK,pTˇO. NTpɍָIBHJw.?\5jEgpJR$B K#3,T~ |G} C̯\\n2'{ ji|lIP :tP.,S(5UJ@@&>)^ dq{` ES:;עUqR#&%'W1=@$z*/ᡗ+{EcEKnԼB'XYtKTO8_ߖ"LF ХQqR,v Ğ1X_Q :2;+VlB+s{uD䝾[M6=Ji`cg;R`'12 '&*p}5u⢴Ԓ_̷),2*Yóa877ΟC J@s<TGHrLrr}*-*|@2ځ>o.{#ZJ6?fNi/p;~\,AsFz>'iȻ[^Uы׶<+); >s&gW,\5LK>[}}i3*~)?i ؎AgRR@TYyVr8A;-T&ׅd̻I Q|Xa cOOs4ɑM*Dr`Xf4ZЄM͖p1A(&߬PM4KM@4@^z]'~MrlFq;$4l3R.~JL_X+)VshFM9 ALܕ\F h_6H1֒ZMCvEC6;ݸ/s+_O~A1{5Y.t>x,aYS{7weڊN$o\ z49-FZo`zp#$Qfpg0k3Wi>y^ p,f',e>VZ$/0 6/]N>^`3H[OMl_'ﹲE4 V87Ok\{-W *JS{\"84!}Kfz _o{e:?e_xYfrvkޢ(£?&A@K>r PtopvU@FQ^?= }#1GDA{1kz܉$u}wƯ `ޠ/ Lȅ %̼|\m\[ήmΓ+, H~)Dzyؑ"7S^~H3-򪧨]U ?h죲Y ,D^:AJ˺;`UYƚ036p tFrt 2>.]8#?/ek76c{'RP,ƍgWJ^$uE5FdP~sv)3qt`5JȻiP+EX֩9=ܮTH1s /YB.Vф<C*#$dSPSpԆuUAI  h,8h/l[qM} :(,7؇Ef נx?IxR-f|Hw3;i}#JJ5JYEoLwbsFS'_usN煞'*@yv|DTRބ*8`b&:DɎ5զդu4̶,Nqbn+LEPEd1#rZgx"a/"X| h{t.?kwGg$HٺTSNܱG$Z;P=߽ڰK]X:2[ Nw+DnNp)gt2/vqXBDIYFIfzf9/Y+J&}l_5u&LkbuwL- OCZ\fwhg?$HXѱ<4 eҗ^ڟa[R)ry04\i1>8J#NZ/tFpɁV)\]K12>@!{׳Ux+Hγ*|ha,b+ f`briҏ:n d09MśM^jׂ:ZH HVQ#ҕ(؜ `+i. :qq{'O?k]Bads)98Zg;.vFe 4~PGnaE3|k)&3d߽c=hZ" +û^kgRǾHKJ5z٥F|8h3dM>hw] 47uPGFGbLeXЩo&zWl0~m0n⩰+Xb4byy}n}fKJ]1MH$mbђ Nɣމ[{r9 90{"x-MR,L\@~ux٩E#.8ivRpu;zs{/4U*ш"d=ФSA>: ,U,`fj?QTS'
  • mI}1op`s>DsUg{:g< WvU>Wcilم<tW <>DlV(nϤu-9)>Pv84E(xҞѐ7fg ‘c OCs\n`DUb: R"?D?אN!\d6c[n$G)\DU=G4Zֱ`C;xqoڅَIMM-eBJs[Ɲ"^qAgđibAbA:?pKF<̀/3|jK}2-{] T1^261‚˷ЎDZZ˸nRs*|q;T2wxCįm̠ ԱGIeDit||ɩ{{&WcWG1_iVXÖZ\^wJBLFm_l9Ky|*2ͻsV#u%|B>fPP$~MwwFN#OȾP&Y"?\n`pU>Yʬ/sUTica$>,}6W_U.k93-Oo}m:gYFF~ʶ! ˾-QD 83\s'񮞙vXhZ:"EYRC1xA:wIF­ZLWWCv2}3-P@m2II=~67>&i_MrWz0A HuU33Ϊ3&AZ4f6#YNk/}[^c'B ;誂eAۧ unni65zS 9Ʉ$?sN[@᜶5o Q/EZV}Dp5k=rfYppb0X5\Fen&Fڜ3vח;XˍBdIٲrǥPw6-3א q{A 5 gݵxTD7I0=g;:dRXØn0T ŧAdE-i|$5jt?En<ZR C9ɌޯMׯ–o<\>͓9 Ȑ5Uj(08Z LZzr1I:9r 5F3^i,KfZ.ãS~>>B.æQ~3X"hEJ6&O]qP@[dΑYkʟہ&05J=?/?e/ߡEu8> 5%59y*C ]ؠ丢K9}6ux8y2aYSM0nGr0ad[&oJYxEUj̀ >sW3Am{6[ !^F?A#vbC½; FWo5sP($;`nkB; o?Qn'Tj1{\XZ6/;H@`Cc_ E@sF|Ȗa6i]JKұL &@W& J la51zV7{ܺbHT:'!{- t EVʝ7c?)yܶsdAU$@G-NQ =G ++N.j/x`݅]g;?tFcaO3cfK2WrJc fWYܬ|0eޙTr#:4w2scN0CE6WNbd߾JYΟGzC4ws12$wu.u7IxkĸI=ջvl45*g5\l/]w 'c2D)Gu}-T6 }@'7R[nKj AB^?Gt/d'g)- 71cXOE+ZS|x$]S(W:iکj+_ۓC{ǎ}0@YݎOߒz04sQ% FqnNH"UؼĦ۶ۿn}@_fPG/ 35@"(C%"VD?tҁN0KnXW.ini $H^aO@ : ?wZ (YsUm^=/b 8ޤo kA QC,iIM$M5 TҢ~L86W_^^f%a,vC'ߵB>!^ۇL^W)3WEj$ڣG`zĿ:23oNWk_n69*Nf'* (*B4^q50dcgZ ƹhX{| Jv@GP;򳟆f((^y0YM!24gپ*yhzR@G[=?ɈOo;e%_Gj68++ث&WOۉ X3ޗOOS^5N$x#ʲYzݙFǺݡ!ٕn)oQO`cyDk\p. g#O]}w۩A=iQE_aPBI@Pee}m~]f~R:bMZR?TYj')Sj/h(藥xx"* |UY5C!7z/XF7cCFPIc HQ`^!i2,`yT Ð8QBX"d>L t\ $>l3-jAUYQRTi/Ud7j&Ow9btbB^IȒySzJ҆" /ι.Sp:iZƈtʿJo|kJruu wǨrb۰Ƙ||;?N`d*3>Aҧ?bhmss 1Èy Yg ln-][c|W.GQ+~R0ؤX] hH{0Ï [ah-=$F0neIzҫWJ9qaNyX Λ^@gc-@dkk6?i4mfwƛ |r ?Ҁ-B=ܼO>‰dޒiA/FT.3 <42 C{]GrW 96&{Nۏ@!*wpzrggٛDAL\%>eҝ՗*1/< "OX2O*28AQ~HBj'x(> c CZ0 >zo|)>mrޱ/ʙOy {Mv~xRSӮ k"MDty̟Q磳Y_ńI}zC\&f'>ۊ4-DPSI%R/J{>jno#N$`3Uk@,_\̭kpZT8{vz9ÌWFDUP%5#Y8vGD3Dж> C>B Or'gFˎ O]$c~Yg+C > *ﹳyO8f7‚tSGMDFHA7hWw$e]~xXʞX3YQngfq*s3;Y`ě2=gtl8mjj,deXXpE,ɨQY|د:kNX3+\M@՟.&:JyR$j r($<"xLFp$.c&w@⫰t?ƹ^KoúJKq֐3x>IWt{.8ɹ xĵvḡ*.p&CsOwC$fN:]l[ۇ;n|gEg@ P]KRx8$*ybݢ,sےSI^|WT+eZ&.^nQ gYD|DL.,8z[Oly 1,bkq4σ;cҸl]]( cDfc/v*1Xzo(l'K 'z$,/2!I?SR-͇4r]P[P P8B!jо_c Rl*ro™H'(] |ދsRPٴf}3 .+>+C6pn! GSa(gZ0pfta/=(;/N{se~2zl+ Et8jHc_L}K~}KɈKj4E Gp'f?U_*.97[|{/Diۊ* {K4yъ2'6"si6fݫ:!tf} &_=>Uz7OگrbrGw2[,Wrܜ1@X;AojaRYD12Ñ1&Da/:8&q㝁R ,qM-yˍ0 oq qT#QL8p$0MԔ%rNL}$2.bФ?i@EC<{[4Sby0;Y~E#/~{%cpM8\$<';*fXJa=<sYilO#V CtXߓٹǀKu$-= ? xRDʊvR>H?iUjG h+C ^Zza?b`&AdFȝ/u+6uX} ;$a F[ρDEI>1L[պ. fMVLD^FO~c!L(A:(9 (Nuy (LM%; #[ lՎddalB8ҭ f~n1lQpȩ7j7NOh<. Dk=9T+.口0]۞zVS`m^bU#AWI!Jid U­;*p<n,''E(0M0?> x ㎆yyi1F#]cVwc->vI^<Ԇڋ:1$5C_E0MߊMm% :BMl;0RԓXʾ9],"|2\pElQ́u5zAy%m|*׭7FJ}K1֞@U zmŋ;k s@ mC8i!&Nc',l} S{A04\4"%BR),0f xͨ$,E;lnp1il*Z7ew sN┱ &iNПlww FdP]3nRpfhVFzv)?6^0p h*)Ŝjt3悁üqwS Y&y߿>n`//:90$5ftn"x Z"9Ka52ѧ5\ʌK$*|&>8O9lqx].,< jLsȎhۊCN팱#0ߦe(ؚ5;|szd.ߚjycVYY+H)c/rZEM>lUX@E9hm df\|ρ̷q*BwQJD GYXƛ u}Ҩlmh?I{fr+'L9\MnbA`t,Kcp/6`3 HS@~sy6&YY@.p0LEeS>c;XxLXo~Q婇$B@2 ‡GtY:tu**R`9 ) X dC⡝VZ< "pI`Dz^oo(~p 4@:Kw%TK D=WAtE.`>-9֨V3WWM;iA_{ecs B,8ble4#9pR(RwXh!5-=rNT㹺HA+tG"A T`|t%0f;x{L&Pe%0NRң֚ >FpCy5\L?V(Ti~Ab)eXhZ!W҃XcCiҭ_'8l^SCl}A9vӽAOЍPwMipХz|#XqvGyI"5 OtCCbVHݔ(_9*,|XO)>^13t@%!R4$|%2o=\R؄3ߏB{ͭ;<2kz5Mq@y?/ ^E9f(W)I{R,(,M'|I`Y5p= -=L!6ydm-jp$272pW&-[K}R}zg%!w_hbqM1k04 RVZzuEC)xIaJM ׆\MN |>ES4焇 ༳9w7C!dA?t?hV.[˧A\~ٮX@lg3\ˬ7HFN'wͭ|գH`>F ꀱ4.a4Az-Nkވ|#P/>iC7m"NF) & ubvp DW&.e^/X$"-*XK{_8۱g[\_դT,hieܻ*9 =hSn˕4<`L~›brr,sIz{\mB4YX̔NIlT1+K_1qۖl)EOA3 h/]f.w3Y1{j`yԲ.5jRמ!6~V;2TңLbiWxr PuU N&ucnl7/Z1ABHj£ʿa[l5ϵnFѕ@?_ ko 29F."֮l=&MbVo'2%WVW ZZ2GP$<'z McUgJcăeV B"3m(~ o /M?0&} 3eNhrWMW42vM +&!uN|%_xeJ%2nQYL)y k rU@uOA%dOS]8g.L)Uѿ5;n.f R5|p[CEݥA JWػG٦ 9f;3IZvvinkG< hZl-{iڪ ,ǘ(3b(in*Jc\h2*)aɹWm43؍zO(uTHxg_.=( 5쌓?8ӶXy(դ]M](4CrlSo1q:7'v ~y[F%^$?to(uwŷːIJv ryĒ(2#tQSNnB1fғ{)4?B&o^]2mGs[IpOc0y%^<-[^R>6=Oў8E{_aN93!S3`=ϵ͞Ņ.B:M3uBC[OHpwGF0Q}9k@w!D~L3tRXiJ ]"L.#0Ԙ:95ﷅ7qÆ5|[hl+N_i{0v^#Q!TGOd&iOEkպ41G DYiʅ'U$!h-- h?qS4ngO?A7\_Jp!ƍM!j:~vòB$hk$]zK&ՃǮ 7:O 3bEV MDIe yTk@p>PA[zYGu^qZ&6j@}8ZriHeSDmfZQTҢ=<(6r%`û/爀#&,JԂz)sWdmwp@C0&LL0|nb xX~ҙ)4&_j QBӇҨ|Xɲޞ+:^L׉6jR! 蛶RUn9#P|ş>G#( ाhGA `N3TJ!z~L9)sZ*GN ۖ pvyЌ0;b̋ln@ut1v A)VFa`e4%:(ɬk5: [Z.@eDHuѾWح OV8a+ &k8g AhO`N bH=vOyPztWe}LY܅$Ǔ)b/ejڸTm#_5$`'X7z4%jIptlB#:1h\iǶ%8qS/e.^v٣l^β ,Ʃ?V5nw oj%NFE蚐JW|sb+Q1`8{u ހc?L? 57sB{ҶzUmS侓9]P{ZNhZIdsWf~)I$O z5i1 y*)SZ՜!Sg ׃y[w['?հhgx8k1Ӧ@H vId4="m.P&setx3앻E٨=8+2[딁LW95ݙ9nT,? f֨FDsxc5} Y6^ l@oMv*6{"UЯVzWZ3"|*B/r$]d,5#եR&8a:1 1ۡ)DXE}x;)D誄̊#'l*S֍UGp&&eh?~Mtؐ9lu IN9yvbV4QXQ-!~5G꜔`@ 0b;HΤ64UmHL\z_:)Տ>ؔVe'ԐudR ߺzo gi o;[ zgX":I;貗Q(oX4Ɋ;f!,KM#8+w̺^3w؄}tP;I<1Qz-˭nkO͎xLBKի,#t,3IW uZIw'",`;O[:V2`$D. wQ]/i10k8D5r+1Zd;0Yݼbg3^ٗޞJeYeMOQY0gB9 kų%~Dӏih*R}y}+%|g𖽚JLy 3\+aV^/˕/G'\k(R(#$S%r5Z1  }?[P<_!Mt1WWs#ޖ6| ]z?ܷoY:ȊK7G jIq_@ %;1L0\h'~q# WyG3<͚5\e1ֽbl'SB?wj O cgM[,yDʑ+qt>.Ѝ S!P71oRu˙-Fޠ֊/QMh\MaAM=]+oCuy;eV]{XLF')[iW] ;~$'mĢS*R9剦, ?V}Nszd; ݡF^ t Z$*cԚݩeW7뫇l+*x,&Xu#ZL4_c9@zW/Xisc3i$D9rS۸顁:PS6=H[fzsu]N,i(X[ ˍQw@39v~D^3cqm_XFl"}7佐k3LL }smRY&4oQU J}mv:7`^`ݔ2-m+)Ǘ|m|"BU92I'g:?H=`N/~.@f>i9iHvȨnڱ~es,jj:^ڔq (`=&S*. @V e V#mI14G2]&@[zPvu)P?3SX>` D^%#` b_Jq6xf_nz`d5lW7\=/g``o,+p^f7dIQ?/L_ks"_iaԙG1?lM3c1|9)JV< |/ѫumD1ij-4PV.BXj ܀VpW؉up "1ɻ\ܭB 㥧 ^M2@D1 bu__h0.菔1A&Fruу9!+rBʵ W NN3@r ZXcxM%5L͊&q4iX\ub?-56N]ࢰ~땱+f0*W7vۭrZo>ĵ{Q]b܃t$9c)v.[]hEО]bAr ɯݎ3h&N=(J LY*;'v$ 9=t=xM1_үrbOnVjOFVy:oL%&U=8#(?ȫ4 ɔK$!6@D3ux?:/v5P*ܞMvoY۬~嶒KAs'h(i7!9zĠ$ URN\+ .1^"&8OuהHJEXfcFR1cm fl,"-^:RDgڴ֜㏰V93-khae;q~˕~u$Xm[c`^`)QȰ:އQsXoC\w¨8%\YyXQtE cGLw 4B_D{EGr6! K{,f3:&ҚBѵum`hlJJǶk\=!m6:~S:F]UvMlk5UV~C SHMxl w&gIjɠ]xcRW aHi|2سLx9lq/4f OcPNp=ɴF,-NS p&u%F&$GegIT;/{sѵbv*^oP*Q^=OޏL/{cp^%a(.ܱoW, #zHt0J%Ys w^x/C5W[cݣl>k:. A /m`.=DFv 2ttКJAAi_Jn_|lZ U0mli;[L[}bR sߺ'oF:pɆF^:DV@f_%{s@tXe_Eert0|g/RO%P^։0(d?g,Ẓc ZHf S0CG <<`|?"`TT= ^ "J) ~:Z*hu edPD݆>"#*nJАxrҺ6z#E !6ki=Y~X%w-_1m@C3H$?08W}~; as5kb]=5찏Hl[x*!6r}-֨q+\Kb[Bcqiić;zE sc);6a-I.h4p;ATPYW^;_%𐆎W-Em Vw^f 6NJ\z^n:. Ed ~!сWcZ=$x$/xGg&:=Gl rQUfa[71CY`!`ٴ,{G*Kp5SpvhJK7 00*vӟS5Y7_@él+ˈ㷚KuB'%^x9+tJm>MXngQz0`}r'^r-v=w`H|9?RHx6.q*ė^L䉨7 t J?UBtKXܟwi B  1]eC:,gۋ ̪#KI+$r$Lݨ6j e1wHsNITpj,K `dÑgAfH֨P:G;h)P Ox;T|bdg SRq iWT݀w,i/~}K>RX÷,PMJ6;+Ԭ"jϷmT[gB360ĭ<<>/ ]gd1Ym)>{O.T:@7̈ض8!DEBO]}?x|{|W9 ߧe{7Lci1Q=翵Wfײ/6bJd󝋹w% `؋@T MEhmS@PoB_w[xX(c@u"8_[0C9 ;K;J^.S|OOgryt eLgg^|&!.;yp$_rXG݃XDƦ Aԛ :TUB/|0cxӽ# yDszt& f1/ٸ::U_r>؂~ɮ y\ ؇Dk,)^:.-6Ӛc\iTo7UM.¤뺎RCX+SLZ߰x.h/%sMiڱUqAzW2a ի`q0+) .rXπ M MIIgep?h# j.؟:sH@jv=Sg '}G铃vF+4i>zzGV b$+_fAMHFA] gulZ턱ڏ1&%Mi̤@[V.LЌ浂ڞabpS~A6jCNSQ~;RGZe32k {%THTo pcdb1XJ"8ާ3i(^><9ބh+,~< 2OιlASNioGğztc922{i€20}6s,FlYNӧd2lHgUq*a-"dF_*KUİK x8R(]ʝσhtL%G03C!TÃi`p|HmP.<2 sJL'llmlSc V׋W% &5uM,3\v_ј6%`\(Y쥺<ۣHĔ/V$=?S/ WZܴg'ŠbŧQ̈.è͋PAdsKA  Hpۧ7gV#Z@m1NYuK6Uj=l\5%Ci]1/vm 9V`$>r*$JtϹLvﴢg[~5>^gGB֥eD]оchq}&y :7 w&TL8ic,Wmb*ZQǶ[G0n~ph h]p|,GGJLp4?6vh6}X«Kz2u$l>qOeλnc6Z^)"_0|^''4"=6-MyJ1 D֮Ih \kqBL Wzqf4n< UbI}ZzN9geXo1֚>(Gk\Rqօc[q#mh&:֑`iǦK5S+Q`JU8FV?sbk\1?36oFAFA6Y~kvI~ wuo/UKnm[(PWm}?-??k7tfަv5 Ո3_~9M?gD-mf1ɤe|[4c$Y}<[w9w=dڗ)}[0ok_ೈsGLQ7$CCVb 9@m2F 00C]g_0+hMH&ݚ5uyB U6:\풐c 'BVE E[:7 񜎣PpEش쥯ɺ(ሕcsp;X._l !&(G Nw$=z.ud"my& Ll@!<[:c !aPk-7F 2 QcGmc=uJY䟫1=HqiQD1?c8AocQ_?ĸTz'bؒGO `voxq͢րS]/L]da~˳ZJ9%Q٥q`l{/аF<K4oWhMZ[ Mb;0yۮ(,cWZ}VRJM =LI |+-%'?< uffB$\iuY;\%DVz)DコzS*|nl{ƴ}W.hA4*ucAvi0}Z +aHN <V2&Ƅob Gses_+kaf}6Z<ǁL xY?TQ֪>ʼnsFE9XMV.<:D84:GמEWLaT2xGDCX."l5gp3Béq3gh!ػMAOc$,gwh__D/|uwZUF帾/E=quLSUJ! eX1\stn_}{BHLLgZ0UGrCUvQR@4n^zcZO}msduuneSM.)|'Yt-imbdh3R0 3?,׶8EMD5Gv6Ons Fk 5Lx4E .VaY)/E,@q{'ʗ 3t/> \wH1G 0/ k^*BW5 k^pɨų;/&p(*A+2 nHE'홟]6)#5(|%ixWօ>p@Y27ӽ]cS 41b93Ѐ~pn<uNyY$F!ES+_zb޻?$Xb2N=آޥ7K@q)8~z5(78-r$SX|%|N/ХD?WWꝭS !/sY[θ6kIʫiԑ0ĉhRW9r]|=xe ҩUƯ99LaFrw,5ZfGj `]I1rES1>G6]o`UQ h_{=0?|,y&.x3Hdu<2j8Pz ()xy0\; ^ACܖӢU6غ4fx6'Ɇ /kW5 cmm2AUW "vRh%wYFwU5ݰ] GXBxToi#F:{ޗ@CG QF2YO\ c%qpUuKϚxEĬ^8ld1rDN{&G5M=O-̜wu57d/%gdIhImZݗG s|0:3#9ED2j3+d+3ŕ@=^KYA ӲtI,[*:e/1\/-?H2,77ϧ.LCM1l>s D#9p< x7w1L6w 'y CpL(2غzٞGh!63ۿ[ØךCiGC<#whX=3v::('aDQ7x>Z<խy^,,+QWf{(al9B)5ͳ¡:AxLHH7b@B@Թ̣Qץv#rq`tUOڪW)B wBRo+:Q3ź)K5SΆGi2*ٯQbf+D+bUJ/&Fh;.ZӛOfjMőϘIE>.2leRɂ\pKVݹ?K9 Ӟz'U•X6H6њ,xLcz,|֡f(v"o)B1.#rs5)Iw;zPHeIz3j7!Ż(JH@IF;%<'/s>ب 28mz,6j~jU*ͳj` iJb{{)>)[[{ Un擣d+0xCL\i!17? |?QB;w$_*)ǩX2~ (B鎂a!lZDN`"L-cIRbj:E\<`PG~5):<2!70p^Jg"]D>pq3rzzԮF㔅 ;;#ʓ 8צZj-Ց S8Ly#4/kt o 1$7FPQ/wfP;:d˃.Rl*B>`xMϪ&BZYAW7 Ccݓd.3x UIafCUѳMNQMuWWFQ3g2](=ziHӳ(rBbdtqqDNF ^'QC #\ZMPXǏll3ݕogUgsSӛYz9Hѯ 8שiڬ6Xo@`ӐCj0fFKL)2p .>nF~:/KRbZq׼秤9!]vttɠ,҉*0X{74m^!HdPpl>x7w:eFn@/Qq DcGm/AD9`\PM'dz[)Ъ ٿTe労bOn܋Nr>8bLOm2Ү$1{V$3*Ine*kJ>z\'L e=^!}ܣzD!']\2c;{UǑ`xaAnӉ ¾h-V Z (6;d3+ve^#`x:[gEΚzCJ3-]Y[ɳ :Ϗ82'ah#  #Ʌs)4iLGf'T{^+*f>q- tp/!܆ąfzL@ I|,nX1YǷߧэѣ2KcI;b5q}vKtlJFOpf=RE{K"qbK8~#+Y]ïlu!j_Q!ê̐q,F 75c/.-#OYeD}SPg҆fғ ׫0l cNLѓlSQ G;_Ix?O~Ô,7HSnu125խk\C@ċD\Gmcjw#"w.l$qJסK q0%2T-CBNV5J g ܧ" #KIdn ʙN!V< 1lBY_Ҙ%tkl|$J'(¬1),Lv`k\ G)bnO܁!o13&u)jlpd®^R?K%.g\}xꬾꠙiA @quybu>*@m!\ ~uL4޼΋:1DRmiڍ`W@;v&6K$"yN#CmL^d)=o>AmӬr͚z*RTRӘMlCczwss)^skP)|D7" aّ"Y7+=&U."PҦ^~ %o8&F!+W\K8͍S7xYʲ2ޒa2k5?,Ppkш`1+.\}kٖ.H׽_|帒 @YgSIܺڎ \;H!Y.3wV%t;DOZفglgyIMH;u ?vR O]#h$eRTY9 OWF%ѝf5qUQФBQuUl /=Hi`*`ŧ :-",V\{QΐM*-&#xv<J6<5-׈ZE%EC;Y8pr;>€$$EMXG<'aʼn"߲P%նx\bsP ,Z:llƴ^ek6t#hZ*lڏ&Ó\[,('#6:l5- , {AY7^>ZaԠ^iC~Ϲ ?@cnLG"Q=i.g [ݴo*XLaN!#kU,V㾯O+,+:RyXWwCOEiBf{[ 11!V>`2Aol(FSжF^K[Q0;{o/HˣRT D|.sn7Vhx2s4gM7Xeڎ!ι ❨Rߜ<ؔ*EQ;mp8'Ew稀 kX"\U}K`Ulhr!|)y5L&J: ~6JIX:v[:uWFw6hn]aԭ61P #6m0\k!Qm};Ur$C$azdHDE\#X—MeÝ8y aUhe?)%QnYg%5/Wi|]Qq}>KPh7@ZQH[\lf &7yS4D$?cv6 Q E6<>q[ICd:EJ=h!ad I d$yꖘg&0M}8MO7e3.~_v%9$9tr=iPUsqn/ 4y=SwaƸT>J\%Xfsk;jcxSc~XX?zBfX[k۔dWEv 5o+tZt(gv&Mwj.lt =cfZ؆Zl`Lt|JT YJ qӨi3Ws܁[]Bx4f4S"r#`~L(ImY pU )U}X,OG0JI?+S! !ߍ@^Zĸ g2W yӛ[o|;M"삵ATrjc !W2ȬBz"y_:ĖtJ YQ;Irp%_X}(@X17Wej/D@j6UTu_@HʗwvSta̢bhwHu\wticv@ǜ-Pث2Da0@@s/g7T.ֱXVM @҅XU^!v)PpzɆlٵ[09umyT[Bt uiNxcvdTAa2 gPs3F[VI#)orp,L$1prWX#y*-8͕RD;k.Gom5_t~C~=w ^2cw<7@jU"'a_5 +ly D!AW*٥î̞;xk2OM&zW?A9o/+%c-H+n*&UݒfY;lb9z*< `s# ęEƼ!.((PEi;%`Qw:x{7NXH/\-@>~8^7$=i_,x>/?Ќ3ra]E{Til=ط~pD cEYL ɰ\r).U~{SA2+2z]5$LaѢ%9 P a9~v5#A/ -[)(T.ELfK!a=ĕx*0F/bKapQ邦oﵴ,&>SD2,.5l?">Ob<|ȑt 1* Œ>q, M#_P2qKo}C'Ia: ' -q}h-0Z:A4P@XI.Xϡ[[ʻPUgZh xvaH?>qO)zFV(q([ edoM)D0YWL"<}^p>ezrP*\j ܴ}2x?Jg ܨow[e%Zq4ILXb^ xU)j<0 Sbz=hIKSfL4Kɧw԰q"ȼD_5j `^b/``/b6Hy !jhs@QnSu8C*p 'AWǚNݞJw?4JkS(fX+vjlN ~׈CsaB'C[+o 9,ԁCqe.S#WKpԅCêڀE#_b4s o')\-|kԭN=' e|T~VɍsFm)8+%>W =' q7wE0tKT s`RцBrvJ>)3i +rh K>$Dz2]p!`<]Fwh JYQa,+X5^! 9T%{Tvw2c <@*yKo#}r.@י.l^rm$1\45vpB|BUʡ݄p䵟l'"BM-<+RjA[d5 ɓ0:g{g*sh؁J^ό~?Vxo uP CR8t $;^L*ש'N$wY#U)&бP\F ث$>/qN]i%, RB&)\ g5-݂;k'[Ж44. oe4kX' 3IyƏoBiIs.5\F-\Sy]`2mkԕi@YN]auq }5)H%x kwᐗk/URrҔruP,_hJԫO"G߂/ Cv(9|^yC" 64%Y:iCE.i@?dQ = 05"%G' FӸƕԾWQ%<$2^v+ޝ7l{s_-?<|d(^1γa?iƍ;", ،äTy0b6"5={xp:u0'kPc3,aaVj94-1l4"p*wgs}h:*eƀr*\cgu>UgaDȸ1Hzŭ]唞o )G1N6D3Z}e7sf^ͱ}gT)cd⬡yBS:3E‰r[_ݍ2~ +Ǿ) 4Yg, (IO=ױEx({_74Lq:G}97a?F'lL > W1_ND#! "BwLFq.?S3QC3flHz`mVJB)J`Cǜ4̓~ukG=@d6:A m,ۚ YZJzxC6|k=Q>{庍JWCpx΅IW]<[hoLq|ۡZQXѵa5?ɹ;Okkkt?ԦQC$`14~ y'PB`/CN{_z'dKy:Pnڠ?\lے P9`] 5ev "Cy ᩚr~шRu>+X\RUD ]s|"]j{YUn;9_΀R@M,qguH+f`,M8.++ZVֈ$O - ><8o7w V>!i 5PCیllmmɹ\*)ޥ۱>S}!"9c=1+ħ^wPkdHlU!%cy(O.m -\_Ͳ cWpb^":|wҕ%qV#?p`S%S;t3w WaNx5zPor$4-XP@a6@ȟuExXl~XlN}<zHl}Aq.{LJfPU|Z Ccb{dR R<216$:l WĊ˙aW},2V& :5oi?2u&zL M#jyG|@P:x{$T ' (Z7hODG%j]LMx4<8f I \֚rv;H~!/5MWɦ=V& z5LHY \N>6w+se01H6ت>bLMroJ(77K2n 2Q2 R̂(u!"x{їhPK,QIT+ e8LV3 z#uP |nJgonZ INnHudM-=3KSUK@ D>8_U)`1_!EybF]CEi73@N9& `g1sOY`$+(Mo[;(3<^(EBwL(; a.ZEnYw6:.ͼ _0!~-&N= ;&J6G|fP k8U@pc{TOU)85T|8w6dS^ۄɄYp6mzzw[蹶.\+$dA`ue Q\!I]8췁tڸF xw"UKz <4Ÿ6䕬f)W{W>‰*j9oրՙr"ա@u_ڵ{baWdb)aߑt]k8ѱaDx8|jobŭxTj>MUϋw̥f蟃No?Rt#)?q(8u^W GΎoB9;ԃ?pĹ;/*;8*PY]FPT0<v ry×^ 741O(en#m/bW[yb`;$KP+pX0f?о@ :n gp~DּV׭F{WՊ/w๰:.L n%u6z'ɻJg:ˀ?lOT Vbb:"aUT"&b~11tT?OK?euHwA7?ˉ}.՜qwR~Rkl{mA)51j$_LQ0<ꋥroAlWD+c%Val診?hyLf?4S\DUE@R1{?/FmK2#%ٗLX1A蘧R@Vn@`j O\X0'g&Rbz7o8{M(=tu%^rl,nYΙo+od Pc,*kۥT*~|20kVa-e# Hۛ ӋzrbF x p D'ʹi!;ч')8F8a [Nm[;vb\+ d ?l~m(4Ć/mmR0*6ϫꙀzuL3dy;XLrL'/7Sg0ѫk#fk2Q;v\WW#< URs?B0ؙX%KKL ƾ%Bd1Srgp q\)BЫv[:D;ƺI9~j[;ђds!! HX&`5b{4>٠xs/y+ uE`z|'PO>FW^=Nd;)>Vtt ؀ᛸ_%[uQWD06Xe'#/[zMg9I6K6fs͕*{ںJƊF(|I7QC Ay%{߾ =9Y *Fy93mXdr9yj5d+ g,Y6K,ԋڤQԖ`SumI }t-m;-gd^= kIjJt|].'vʹFqfL %p˟83X``ݗΤS..)jh#9ˡe"t 2-"k#tǎ2J+Iךm)ܓY#`gזw0Gv > [@6Cw$Ŧ4s'e=O{ ]rwG>v2804!LŹ]手IhZE:0_`)^9yW@(s6"ڦhbE({3bZV c?6 hI';vhi!-H{>l/B|&7PBLm,hfh{-5v)xs@s38u[+뿐̆{ٰtgi֒s3(+1鰞ů F,k6o؞|+[^]u#{&sj' C¶xW^x]VKWV\lz\I``Zd'q0y1Z:\t6nbY HlHƨTՎ Ͻ6xYx7{~T曛/і>o%4oRn-N "C'&L&9ײbmU攔kti-{L$4NL'[aA 4tV34% 0wqy2jυ /[4/P"P~7vkshKj])TBlSSdӾNEk86fK;Z]7Ȼ ͮёA*65Jگ :%֓{х 䍱Qic}3lQa'l0Tg\nɉk |>9|$ʿ.Y2V) ^{9B7_ӸlCΉMnv}w+֘KY5YqLnO0uL2eF$Sly!!0aQC3e`ԙX\XaOHeCX0ZSc`EtZ~s ? B&!CIx.$U7 rfFC*Wt0˻Xo'aDb*Q]͵MO \ ^FJU,i9jwPM$K61-~[էnB%Ejq 0]c,Ui(Ki\ϧ6T2t a7h }t@vy?p*JEPWӽkXF=9_ŘB>'(R2sQoȆMj+ >A,ADZdvWqL3ϟVќZ1~)ݲ:%`t6 M?(rݝbTje˶d)m|w %:;qۆ YՀrn־ dCuj?C+X?pjv?VD.6WګBA`QYjitbR,X$>8M0V`)wj,^2vtH.H8Rkk㧙g /.3D2i b"Wu5{'ƈ&c!lS7a&;v5m4'gdn\UU"Di,J>'ߖBSW5Ik&yjNuےY!BB)?RC1qHRZN#zmMgXޡJb dc`rWEmMmGV 歂V}}ˊXkMդ*7 bmN12"ߑC L6mh`,LȊ>I)-P&y ;ݚmGLka5xy7wE?tÓg9\M^u; ~\/2xyKSq4)T|)<@Q̠Ť t^-%D :#i|tEE#Y$=5}3JFF'gawo:ܪd6t9#n// g@>Ϟ3th EM{.tZ;Vb# xP40ۈԁ4>|FL5ۓRs|ɗ8J¹|[ˢVՠLW .MgU޴G@gUm\fL솃yNZ9lfhϻ!*2KBU%b:A?P\Гtan٠ N{3`p~6l8>1G?"YJlKŻojrEfLo`V..^z]U9 L9CG׶f[2 E\ dzK^ !]`~.gi_ _;̺e]>8x(_Yww9KJԈnDk/ǡnכ')RdHB,twgp [)Id&6kg˧=3FH8f kR e9*K_Pѕi6#Q`jdpn=u=3 #nM%d|:D5+Ax:~cD2WH"!@E9 (o||(3P襣╌dr,vi/)eK(4!>9ZlrL$-("-A/^l~JQ$21)mmzq`DĽEŎ$&ԝ(_>}j|$ uHtrs`s>Ms7Z +zngi`E齹rœk>މ MГ Q"ZXzD'cF@j(٫!$iv5+ Ad=#sxer-J_/۰OحղphEbEe/ w&C(,.VD~.c+<积c u/qd$gPLj۬az*l@鳠PWu/Dq֌|qheJ>I,1gSD?nV# ߼F^Ό$xBRaCB82\ߌ_ ]PizR蓯>Ǎpu$nTZmKPv'{pV!>%Z8+~B2iIuV_LB|OS.1dA'Dp|ȁ8W2) q@M’/ĹK )N s^t\R˙f/L(?Qj2%s7k eC,'5pj0gL#a9j"%W+݂yx< ? 8x(}lᵦMmPbiHЊ1V9yy,jǪ +i|h䡶uiHԠ9T^6[+ YB_Bܝ,0jͷ Oï *ӽ'ةs%f^1#""gG:CxP (vbU܎QTTm ^Nt>)xh̟{Şea΢[˛zbi)NObƌ﫝_l}Mhm! ТiJ-򐯗k YsV]ؒ.F=MMbZJ1@sYp=T C=$,'\!۝HvkL|+f0^oNCNJ@5/UgY-,XEL=B}Qfķ@ m+f[F()iC/>&=@>u ܰOÇۇ%kxnrWAi_|w[ IMgn骕>Cj!*Eoq2w0pY__2}|ϊO^%LkM7eJBc{zvKLtХhܓz t_!@e oFGb;L6_PʃYLA4̓XƵխeb `X) ѱCbPѭuoOss@WgSxޞցjt`Yr/ \!3ί8LslnGZ<&ZawMtLQq _(A!nyxZ7Q8D# Ɛ"gbJCx}rk5(((* ȄEtlZ0\]у|n*I9nG),Ij![(voiy2J:$W O#bX,t!' zRpIYT|u(a<)W~ϯ(H0;t Rh }hG=ar|c1< _3%C[q:^Q֜A@6j D˕U:4 fԧ! ~(C@04c'À {[Qh}d6LzV/@3}j.E7O*mKǮd!4 f]s,\ߜxPLpgy"]9G~c?B7a%uO C}*_B5ڊԩ%C7ҸƝW~  PUb9/A)n;ZbʗM$xѴMJ: ʥKS3~y !$z) ;ZBA6IK9iYJ=V_M'^j9zoǼu¿&P&(0On慗Jl{d 谒&,HTbHkpC,OEkwBӺ0$ȡRDxkN~+W`|+IT3\s_'Rvhί(Z\Qd d2h4>ZuiӸe`#uݔ'j}+.mv" {-)ZNՎT9 Wԍ=e?/牆?hoke_Ƹh{)/nx%OX>\LT ߣ]`uA4'$rj~+9 ^g六g4''KY I#=:C Km_t(361Vq,ӭ1|dc&GE2c]ǖQ E4:YΣgAx } 6W*G8y0 ".{o,Ds_).)SMb(+NOXf+qՇ "+m V=m`"A#l)S.yQ.1~(; go~%ôe 5 `e%m7 ɪiN@e(ivEӵޝpz੓hCL SnԼYMH k+`NV 41lZ=r6Nj%6 q`sM]y+t;N)~v#'v3XppDҞ .CeLo,oږyB{"qǥF,YG;ixf-9=Hhp6G #FZ-56)GOxbz厇d[7'qa.`]`?E;&/JEW{X,Ũ^?_xǻ`W*F7:Ky/LfvSRo7[vbp42tI|Ky_ҥ3+7j~|RH)G V-P/σ8UGd:& 2 5^[%zdhZ7^ 7#P UB`j8[3X̥i0VS[#2P UQP 1Unz%5`ީ3 }KK׳8iq7~e X& b+Dp[ gt]ꩉ-?e~3`]c,lhA 5D§;X;Wu~皔KeG)6ރ:`ͦT僅TG̤:G2;d)rjǤ)hJ׫74!R]# 3,S (n>D4;NB^@QJ.z^ׯ7?O{GK[ˤ)o|IN`k%v=)3KBb ]gTո*qMRm|{J' R [xsY승4N?}U>6ޤ xܝ\IiS݈}je)ވ< rtuD@9htst/p8B4 (oX}7^YAQQJ Pg+0jDVPezrKn*S,M`|b[*}|, قϳLq =6Ȗp&6s3gZ˙+|,j#HEm K H!d&zGPH(G'@.ԏ]8aFVa`/Zks^tޕS{>*e'"мAyHb8]Ikyuz_E}}j JY,d>NI_*a?^hVєy,=lHwlبkcKE$-m߸m 2HKt r=pa0bE@Pxϲ)#.\-1{d8kK #rĺ,yB5jIɷhVKr:rrX4i9|Gʰ.(A{ߏyUQ^Z#S-3FR+n۪zF43kjq` ]b-X2yx3̗Ir 6)k\Kkl!G6#G5nظTF4I.Jn}5F?3t\lu|k`|TJ848rz w4Śh732;P"hjg$o7'08L$y=/Uc0X2Nmѱ~<S[G1[ ť7(d.@e1o G~.n>̚SdgڔeožJjiv-7ȚhoQGkmQkL3O! Sv0!%y 4olUsDEU11:PS雳/)-D2]lZ mH{;ǧ*F^d Krud 1?.X9hU={Xtʼܼ-Qp6\1G#?3DM$Ox.S/N(TdS/֝5B TKb_1@B[&ZziC}jF\8t)fR +ޛ [(lAZ^_zX?#8ɖ0u$R<ۇ$yNO?vn-M5:C7O`&uPbcv[k>͗7;-Y3n]^V_Aژ?tDѶ1\K9 2Ieޘ.{I+j*9cOgd.VQqr}j (q p@p!wLv)]вZzO@2o^ONCMm->`o{H![2N]n h 55`Rܦm3[4C@.tW㸄(Y՝02xDP4-*^1-KbW:ۘ Ĵ`tāF6nPʇ,18,"}F;\.v=3^tmX%Pj_9ͬ`&\6{`Xzld>by[mP䗭ڡ1q(u+wÀGٔr=G6cVҳ6B;+U+ZOʺ+?l]}3S< ѓn_k[YޱZv׾C1lL^]#ѶҎs! oQ(kI/BRH8Rh*' ]񂣠 g猂Jylp6k H f5T7D{ړ/96A0r=|XL.1̨r钃>\q:|S[i_o1o Oe[(h<`8%JW)HVyL#HguH뢻2XV-W 7+?wAz^~5od~0t5M^jKCR+ HҒ*_PCa#ċ3ȍ֭PR !(mdWF w`|HbyŭW%,|^g_^$˗ Կu{y+,V{1hc< pO7x[[;%]㢬Ô\uV @Vm .  ;C#w.zYH,"}Ob:kRbk2v,rg^íQNWFV&35B9N`9_[ӓ%~3ͅ$,sdTqb.D7°JɆJI+;h`Lx b /i$۹ ҧ7n܊ 4 ˃MA-A0+tEkǺ땠v粱.4d-c;RV|j(k t^Z)b>3<౮QY_h~ZNi4W']YoA@+eT= iQvVv+b>`N槛g*DEiu"{_*hKJ6Zi04|,i*YS 7x2coHB9;֚Rx6VNriDÌ:GW,8^:[9{{OSϓI$Qij|QN[K# N ^Oj:i;hnfzSW,n!KL@#l9 hQ7_$傥ảL?ZepEF+oP>yc삷U틌ok wb }F.ezF[ yĥQgG-lj1ҒAzO6. ` L\#A{]"y΁0\ΦiJ'/`iRQ0޲ibUvt1+Ӱ|jV h:|%{Wƒܙ^Ɗ` Z,bXyLΊA-ڥڋ]]b؂.{!͌/i g3U+$WE)D =16 W7=3ek[X'*G+ crZjtY,̫Xf^6139JD'E i]2KlXԮ:B9w%7rgGa.#r_ "^[5pP.OT#o^o8/dϚֱwݨD___D," іQ5AܥKc? )kZ: Nqډ~YÇ2]TQ~*~:nRDr+ (JT &6Q  Z"xMj%h!`uvlgSWGb >G.&q =4gaȟLڽT @3 ]@t |#n+2 $1#6f\9aV2!7Q# 6&jlM^/EK^HJ'9m8ojMc` v!O*eܙgPeIzWKБXk- #ٕS~Wg,vSN77D5VwO̾w G74q%h?># "7XlC[w,~˖E~Fj'LHCk#pR^{abI # 8K]aN;q#h2ΰ܋A޺08_l8{&'zh"QtF6>)s|E)FלtZ~/sPPw~⊼j2UP>k&5\^#NLjnSʔJkd %)V!XyIo[ H;m$ucOen0mqJO\93 |BBkvC8fȚ"NG~'lOߐ@o^nz Qvnt d,g:R-`mJ?L}^ y:RkY/u/#[JO.rCqd+fMB^6NMbp!lJ0ϔA6½Ǜ#eZq|!c6icx9 MHՆ_֬uoŒ鈊 f9 ޱ`dikdcHK|@6vQyTm w%E#d2W "蛬6@Қ\]F>%Lѧ>e30[Az㗓uÐq{o9Er;ҙOi>^n䁮?F``_ 9٨M7ӻ2.nܦV"-uF fRյLpSa0}Tu(X :ܤO 6L`.UGTrXOC .RɊY| XO $&`~w cmZ:{[zUMჿdb?7xI-<'A/hkO)7:-hkP$[@^a캢WΞ/Y@RgC=^K6}~M1>!|^tgmP@TJsD՜8!s׎cD[9HB6(x\ An1ע,.pi;U.Z7i&U(^(y#"l8;.")q#'糷!Q ٯTgmw=A-jŐ*/QXY^`D izxPvO;\&WàM4ݞd]غG߱1E(#,f+Mȇ`<+sVc(lE@C>LȆs2MO׶K] rFOy1Q;Y$x2|[*6R~0gY4dmJemLK!™;\reIC%OmT>JspWK}dw{g0KGW-aIPV/sQ Ofo~in!ЧN45nﺫ[nrڀչ=I,rNԯ 'q|P{h~@xq?N_k1x^~e VJY2hhs@_QPWidX ^^5ph|n+\VfI>vxZh$ՇжN f |Jy_0(;b0=$;~\W(ڞM[j h?PwGѻk3e|7&D"*4]4p21PelzMfhnq1`5~Naf 7?堅Y~!1UdFm1I*r3<-x4^X1Ʌk77D5f_ YHSLVΕh9'c6$ xfTt炠h*kMeIs:0D!1;F3-sgV\≞B̊\J#Ƹ/ج(C!hyP$O+NT^:'QY $+S?,R~`>c"?3n.[P*MʣRMﲒ@cx'ceky -phBp(7?$pY*m\"wƵ7z)rUf FT58^h+m< / 3_aamy }ʢ6dZGkG4vtߧq qzp Ӹ7ZA Tou{/z)ݘ͵EXNckFwק- /.[l2hj P>GA>;"Zؐa2`;1\1dzv"\D" ؜g,}g;WHjG/R&0p k8Owd!7U/ Hʉ15N$tM.ޚolft-7U0sx[)|#A7ASέ&cϗz6ґSJ`JdoE7:N7#hOfi0,[bMf%EHlp,tn*?@^8pQaq[!Chh7*kBT5aeE8 пG4uNs2w1[`;K8Ցjmd<:Pt cEy60ĞNAR M$e`VԈi,G3!y[$BS]@#Ŭ)9L jieY5_.&mȖr9Ξ[Aea0feFqbbe9v%Y hY 'RGRaQD6E,; vCitDP$xr E 8,,dR$oQB~<#XrmۄfuD*@HYC Jp\F,pFY.kUe5ewIF:g "7.Sl%7B=5v#!M}'<=3P3i{>md lw W2*Xy$`c#lHl3Vӿp@{(uq'?_FXlio DW6r" d[$0K/a]g=9[  DXuPlƄ9?vWB<&BX ijȹ)$7QQw1841tu=Ie=, ฀ 2:G#ܳt|q }Xr(/@X٩jFwX>-?#BPE[14zu*m/D*{K僆 >q$ԗhG(Q_CD#C;ʰ!*&A@5Rޠ_*¢:i[h?[():^n3mF6UVAb:#R2/f&l&s8pIQG6Y%Kښ :ʺň1{NiܯT m ebxR;ZBθPaD(U| @0`!vPں.r?Ox@h4p|lB-^ ]D>"`_*?ױԧgC{F4-S(KggL_|9ӽ jE N3(L Ơ‹*0}aO]4Mp`n }H8ThC&?1Fs= ?WM7 kAk+j]|i+3k/ʤ)|#E .61dWd 3Z +U zX&#TZm1ғ ()6y ?vɇ k6]Ҟc#@lfwqY${'١Vl𷕑Ez,~ًiC?wV8h1ZY…ɛp%F[ƕX[89nwJ?ٳ`3l>hچ^G/T +A Mb3s6q6g̀P\dN+CU ТERRڐ!l5pxVx`a摻B"}hm Irj] =4M `o!CMŸMc ?) k7Ǭ Y6Jou2A`!йwzlPIYKU3Tx⣨Ɠbi[]הm~bwl#١ld `odi$:\|4G@^V{a5]ԪൾrrYU)he.ͪ_3`O|Kȁ,_c1Yf@I0"BOl$O!'ZkN>)CB鈱(E.Z'`B]C1 Dn-KˈHgq6 $dVJE Nc/喇wKUuկֵUQ,OZ\N0sV$1= /O5SzpJ7јޒ7;gqA?"Y#QYDx-Z.i[4u`ZeYyo\=" Pl`ob(\^ZX[/O+WQ Pz&h6\YllH"{[>xBaU7ˠ듀-'Abc<0ww$|ꅛlv<}uٜCe~<o u d͍Uߥ΂E  ?0~m[Bmh+ /OFJqg\FV}j.B+ٞaN;K@+06$YXV+-i\:?p7Otri*#n@X?s|oA [ G]9\?idVT;A:\hZ^M0;2 ؏؊/~ͻ+k ,P,> ȻsXOFz\8kFpG-%h!?XrB'R;}U~Jj 3[Lv3} FwawF:yw|T)Ø?Ց`VEUef9;2iHvkl3W乸 J;:*!ˌol~Ǜjg lMJ!sQˑ~L~xK7}Xѓkn2^ :@38bzitvmA_,Da_C+ ՅFscdyKwt͎6.1QL@{\T)ZlR?Kد._;xrƄ vvW.'"ꖭE'-wtҌKMo1-&~19O\gmp+e%^Zu_]Mf*TN{>6F(Cdҏ!BrFW9w;{ CKp3&5&pmɄ_kd4[1cH: j%w.է0ӽ@/Ԁ"}N)c+c~(TUE# .Z)1 ل~ [w+ j,tX|3*4+ya]3n[r:6%q &ch!E;aKUvJL$۹s.Tuy ["w=i:֐Hɱ8)LcȬ&5ڨ+G($ܣ'-4yx4u-:NEw]L%D"tv={JI\RvQrv)C6`xŠޯbYRrɭHHƋ RAtSȶ>x o'>v;ŸzG[',$J=n;=QAl 'cpO{(jbunwۼ.nh(/4o$p g,i(T{4{&Y4lToB'Pbt&2h'_UD\r&u|%8hz=`7թf[LHWهa oG:PQ"7l}3MAy=08kwvdl_*Tr>7 v]rj mXDb9%kp7-3g(u㽶^ Et/wKa0Sg{ShtfSr B3RGFv9Fܛ .ŋ-&U$&Pr ezr8rG52у:rf/ @丆x~R囨lC!Z110VD n ;E~x,P.sFATb'(2hdΨ&MY%+jg6:bGq72B Hye"Mrҗ7=)huj p O Yan<~;lB(>0miT7ԽSb$fJar=;Ftay"{MsKeN3ܘ{Y6LDje1Fg@RhgW[WsUAr'vk:hjgX;ͬEx&4nxw&"]O=0xEQoaNOWe<$9/gW: V>r!;ܪ:Mq{m\]JHUjIM&^E+L?t +G_Z.i%ᦇڂn;+i6УG^{H{¾R]bcSHhcq*FBkW# ?Db.x |`'+2uo9%4qL_dm;ޏF8KYՆ$8ēR˔k)HZУK H<(&!@V% djlcRr>(ݤ;$r$[SB] zPsc2lbAdf_z8UBUS2vc i~梽dnDOA8Z#m6$#6`MZ6&UyQSU։eTa N`2{MYWגgo̎Q rŀNՎ&\)d ;qR_G9z3E.Rl6ʉ` ,~X|+RdTcyT-HXa>bCO?i8#0x3`/CTs |1C U\;e;֘k:/d6ho,ɠҹ?d02W OSRPgb-(]iQ*Y6؎ݫ$D.B6[ h? ,$G¬tJ3)UaB [%IQ-a0grWC+@//!FuOқ0u!tIE P#YcZ $0EN^l./cF`CU<> ہHFXfR6jwءTc8Nwtox%5X#J[-t/WD 7E"aKJZhIH__'ʡr]B Wv1#w1X?=jIuAp `0ެ͌Xku/ٻv “;m,#aP:m>Wb g~6[؋N"& Ow$T]dH-yx*O0ޒ2Yuȳ쐀b;2wZ_oZfҸi:/W&`υM$(Xmo{.2LȋW*]z\hm-f_ 0{#z*SG"8lۥ6Cy (I쭕o.Uo낭A&mT1V9Ją04e2 veL5'2[<} ҔSI<#ǯ8DžSi+cQ$=ɏM!wUOL~bf1̤{9ݖP-:+# 'o|۵Vl'A"qN;xL(ë!|U>H&"l׻WXN< $Z擮;WNmN󸆿Ho1X:>!H,d-QTm?NNlaƢ-BK?F~-^CY%&бE_XQQY'T8')wA[gJ48q#}N_ƅ /f?B X5y.Dk7p{2r*w/FL&^)/ @v(N$ d]N0Lo,)_a4t8f oH13,eö#"js_)Q=+zGZLoEzs>=k[,DN=켰_o+zw tD@47}ptKXO_@ʂ(+aQA7IyR\m!¡L4NbeY*ӕj${g |"BCTޭM^7Prx/SB0 /vY=qZ܍ yH-Uu-5٨ ]!{x?QGs@'bJNLDړďw"% iX_9020 _)nث|)x(a~)P8l5,=|:ݻB^숐%Hۆ?@~6aϙ#ue8MCVw%Te W~殤SavzIO6E6馏d? c|AJљr?C|<ǿӷ׊8,ži)QЖB\s lBcIr$MU71u3tFF96)w]^u+ ,_MW%ZKJz?{+YlW9 X՟9^lzx #b/cF0%!Z=dDekW3VNzq~àdFJfy'Xٕ(~FsQ8XJFQR{D5{_/J/6^g&)fhTΨW Tfb#C,:9m yrF/XWSF_֊Rb.UmѷDP\fI)7b -~QauP#끰X_af`Kw\v)zR.D"em"46ԈHozXBMg'x5f,h$곾|آXVezȓ!gFD(@=?9Rx=*, yn!r;*s6nU*!c:`4-0c h&uHtX q Qܘh?8'[TT8@8M0,1 £jx"L|}s[0ϰr5BnnJ+kb*ivehZڝJ^i,bғwe_j̜b^jԨ?Q9{T@HZXݦxaVzs+u\]!&wQ SPg\T` MA9`%óy^AXjM6/  :(1EVea A;]-.JP6{QEL r1( уg$=wjө/l=U cdX?Ykk8F";Gs|;s$ǃsV0;=S⻏'xC3OcQ_:WCU(3y$([┕n$zRg'yfwOF"dtɗ?Ј޺7VWo_Ix#m/XVg͏AX=-vª֙jy#-:U`H>igE02p.}g w;KטNZ6yPZs<6ߤn|$/:h h_lvCOFӥO=]ՍF`Y_I'aM8n~vqeI%?B!z@b7dFiܒڎ'aШ\tzY;YtP=nFūɂ`ݯTS._堀.`+HrC \5[A yQ,= 6dY ^uY`Iv|rY򪮎K[G+s24^sE`4j2gqύbHsqB"` _ S՟  7m>T=QQn\*Y|} ZSLnc|2\.`09We[aٔ#ԞwBۍ2ssx98v.emT^E&C S}%ɖ_-rZ7)3j-d*ՌxY6/ K)dfv%Ox]sA6 kHLI(L}0",~O bEDvyO^Ң팻jEO;Zr}ca ŲBx mal- ''f3ɹ`V[C{wM!"+ jǫז@uSՍP{:k26(>=L HC_'HhB_Ll34z~aFTg)OС~Td9_׏$ Pc*~mIďn+̂eR+8wfz2Uΐ1qLt֊:0`H]ES) 0}"|)%)Ujbc(a=~xa"3dĻn}JV$mt< pk:>)яtl''Z;yތv𰉅?fGLծRn T cF ^ceH1CArqrzzlnNӹΐ[@/~)5U\' 50OT?BQ)B Pk%{U6YК0D=1awVdN0VMwM%?Cc6T{8+o >LfQG}`ZtI(g3ut2Cqdj!_-cW4`&P ͻ%̀ظZ=޾ۋd AG9@ ه!\ؒ'8s}Nf=ٜgrWpfe9EpcLVmE]@:QA}´W1ۍ>r.y;g z]'J!K [;p4d;eY{xӌZM(v: 0=|-Z#)V@O>" <&* NNt`[Y&$8fbZQͧ`3փPGZ/Rm@%A i|3eq7reyCsA ..5bo|dn〕I8C:غQ+G=y v ǟ2i8%[~W ŁMp`UF[-a%1( ]\ sOir^k.[\a"c-"ykƂ;"_CIhŸY!1 x{q;|*BvBYާ.b8 2LJ\D܍Ij[Y#SLtwޥ賶WpBǎD{KBJ'v2\6vGXqDLϾ=14ϱu0+B%{"%tv" =t0U8YZ^o#/aR}Q~۟t_Z ;kTKfռ09gclOX x,4 }C4,.ݽܘ\#/srTr$ [L |mNJKdivAC6L瓳Cg:B5oQNNQygq(Tw12Aނێ_OJBHRP胀^̑)$Jaxb{N>8W'P`OjT~s+AvFJ0y:(WӀo]Cq~;+a?[Hn-$K=`i)K(:Wz=ͻpJ-_ ,ѷTKt^oʩ6d=n(·lzё]n/ tp$aeF̹6,.eeuIѠ` wSMmM-;7hP.ve{I[J|N?wGLzjWhP0 I">WEgzQ%-Ԙ].D޹ h?Z)(wVe QԈe|?M̩WH)! W}3$M%E"MW`,E>:oR`M% 9ض|SmhF3=T;_b!]o3ɑ %3FƖhwXV߯MY Ա#,,l8Ca$ Zgm&\}" y|W %$a ]Ld<=,ϖI %>, ?ފ,̽%|PZ4C[, P GK,ױs9i6H. 9b!ܼ&N~|4 E5>|xwXKʣN8%_xЊAha-9n<͋TG?^: xw,SR%"鳷q2DqҚltE 9Q?iQ24|5 dhx;L!L-{UqH.Z]''oqV]X>sSQ$vsل3V~ޜ ^@]Y7=}e Zk1Sa!|.}hEz%GSyIt1ݠJ{Y0 N5Z}Z g_QBK'4M@ !Uu`<{(}6%Y{q@سa8>RA (,.z 0(A7iu5du[c9yv`)LPs/0Gj V+'3QbŘpHV ShD"'|Glr=b="]7רہQ~T}'*~=(Hb!LJNJƣQR9}*\frлGcD8+8wAAE#RCf1rvWܷY"Bm1L9G[} v㮁e<_.;n3%sS.!j^P# /9%a"5cQ\oN+($zk:uVQ^_Rؿe3YM8,@ݛPչQl=SBA|nQedt;LZ6cIVkzS Fխ)63#ehnU֖6 +N]oRS lh5=s/?_X}ĤxӘVl-<ʶ zpx8ݍrG`XžcU9r^ ^qDb^wrң Eͥ`ȫ,EUgw$$%Vy\#gbvIjׁ@S %8Ŝ[i@HN{d`"?Xfٷ2/']'OdPwPA0~:|v;S_s ܉ `3-22Ah/uƏ0fU(_F8(Dl.0T3!sѬ*:04" UQʛ 487X&k`ӈ`շ&imWcV Wien67Fmz~!/VI˟FIQ 狰EZUkz:1t&)jЖl>Ks`)u~]kK`Ѱ)!.9%;xAk'mgAkkniZ5vWR!A CXyZם1?G$PGE]E]ٴe00Uf!"TtW}ץvaf22} uC5@w !x$I_d`lh]~wpk&1;Re5xO7W;vAЬ"x9j}zlsO%(}6 -8=@Ѐ BiAS.1UqҾ$JZ^0VM5O:!)5jr+Ѣݤ;G!t% ՋvWot:V͍FkGx@egKn5QA=BsLlM31tHT&\Fեm: v `I*=nn]OA5UڔbmVڽAx d-x%[ rAcZt;ѕǡV..)\׬IT*BWW#ohXKI6ا apMģc24rf{5N,˼Iс9-D")ɖ(:hk~dpo$"&.1J,øB9ԗh^m`ߐ;Q7#<pFW\f8s7fxf dD"<Gi&m* J1[ȊmZVnH$F%`=@VÈI{wbIn "mtNkӟ5WLzX< j`"o%5J4 a)Oh`g鲸l`н؀p3ڣ u%;hlvS|FlǗQ Sfw .>MT{֫WUW[|i>* s** t"UWon69lgE+F;@K$W.62/DDDPZ/ˌ*\fL3V_wrZ&Ȫ

    Tm߉Οȥ@ʝ7VS/*hű4ֲэIWq:ĬRuw`QF4N걢q6YIaGQSG:vbGmy"ѓvPCUkTT?Viሉur+3ӥ- K>3%cZI~ =GYAͻ;[ Cu+/3[b~=hԷqiiI)6 :5!Ĥh<萟>OgdTF?ѫipNz+QfES828\!QÞ$L8 ܸ( = {AS$ DAE|0Lj5V}!W閞*Vf9<)r<#M=sP(Tr)q\ɲx.vpH?mQtP+{-5~iU'|4(]{+ˬ\Fؘ]ItʔAQm{No§,J5-߀?"I888eюǻș s~FO0憹>㢙z3 '1KzVZT|t}|I/H$B#(Q@;idP~X}bצ۹L6֤K›IE̼9԰ǜ_u b,4azTu#zs3&t/'jL Y@~9R3.NzUEhJX=bRa16H $3e)֞~g8!M/$֪|3O5\<r#]gCM27$G <.%bۡ+.,maxXilrmoi8K%ojr"iFX,tcRSRds0fKa_tjH GRb  n]$xbRx,;;Ər⤋EGR=B PëV8B+*~- Dt`΀UEm6&ګ.径0(5pk@+^K&aE '*'aR~@B VtdjU5<C}&d}]t5.)Qn\`4'/;?  rR;0]}*$;I}+U9bĤ1+GHv̊!KW:J9 U;+!%"ՃV!{;2 uiiĐ8ǫU` |LaU1FQ [–o[qWo)B%%!dzI2[#/k Qq܃#D`Վej-M,Qu@y|sRc٫T{^|ʸjzRmTkcq]qn1^$?@i"2o/WZw# KK.lϐʼnΚdEpˆF38OZRt{EI3ѵ؆I}S%|h$Xa=l2'o?ͯ|sp9mܕK͍Fź.륮ͥIecLzq&@Vxe%`% N⹅̄f Jt*xlO &`g$ zg IxqKk:r[mfps+mv39E&Q[ǖMT)zyP#"B9);dd䛩AK,}~rN{Py<;a8 w2*mrG œtp@p_yŠ1ZC;p o%LXy@| J^++g0@Zk193P C=%M|ҞhfBI&p1"N9y# ؞8ryRio{!BoYК̞z Zhcq՛|7x^1Qժ2I{LmyT0~֡P%aX$=$_Tjy,qn +ax8Abm{c.6Γ.  լ DϡLQ"yMd31f+"G  |CI:Tu8BC{ G,Z& Ʉ/^v.U!dyI ?~$8J!'pHrg3&K}=TH)V|{ n46ZN]"Y7A3sK-їO U*O9#f*VM@vsmʌ5܊! _iN Xn:137Im# .Zc0VuSe+V%T@y=CkƥU,9nWbΛ)W!=k F~S3(;ZMKAip6M"di.Xl;|KTfÔT74tm[d /E*;iAn7BM>KPQ v_d=b>]>ڷ_D _J^ύ>%<gZNUGnU5`X\GV3 Ɇq1/͌ҤԸ%i- \b9k*i-9߸YRz٪pxg>O"CϿ쇍q&5m4uP=o5@Vvhe "CRBCDx> =a.\K4i|=1NM<3FG:Gԙ8 853ZHQO_*f:@ 0!Kbf FQO^F`bZQYfK|ݺcK%Icv-.m#[JMY7u!)۩ ʺ;fz&yƆ-B/ ' apm*{%(B?,aTk Y&zCK\撂%~mBȇUzS̿ѹMmY%|p,^}tReu?dt] m {g $so9~ְД-)L=Z\.x*`.7(. >fr('x6 1%Hgr}HZP%=Dk%+7ej3"7 ^!@sTU_cM5|H8sD RO/w>a`͖:ݘ@s׮K|@X<"5'7rҵQNRަ4g|P0UUM( _Xou,(v1^DŬoVg{:-Yz b"BU1x=W.*3 ›rh.;?T1zơz`sIMo)d?p0"L/S ߠ!B.N" L隊ʜAvNRρw`ʊ\8jS4~ _|ۦ1 ֳtS[؊KvNLf Rߡe握X7\Fŏ! '"`YtҩD-.$YZ%VSꩱF_Oil, q_S'W7&B)SW|+9SUJ?JI`(|(q>[XgUEA*cJ\w4$ ! Fx coi]XMČB$mu UJ"9jnMGb_iq;~Mi1JA6d7 Q#Z iVc'sAƐ+Bf˱θo^7LL@vw'A¸cj_]n2d&$i`Hvx?wFReo!M~g3+󁡯}TYk#}m#ߎPJ ;3;*NDD9{p{$j@L?q$U{{v0egh QSz­ۢ11jeV{[oo"_iN/OulI࿠t>y꿷Jݓrg0x7s_Ξ>T{VlkC~>34Չ&gކ:[(Nvw!۽LVwKI[jvӌ >,4TWXt獍Lu(ݩ*dM b VOY[PdhFz6rV;ŀm)Y?wHp_(bm@Ve~7sцt:nBavӷ:CD2 DiJ:$me(Yܺ;tͽ;,6PZM²aqvF; \E1~x;9d+*f/` X WgH'qNȟх5 H `3(x.Y I-9A Sq|mFX2} ~2S?a`HBJ7Dr.D]@)啍L޵Zl ɲBܻCcđW}vBа%_Iט@j$._9DFcTW,ӲqwJ^oJ\KMZI(_ @ JkNڛwXbVj[ۀ=THU9f6K0 $ l"GFWpl}8B3݋pQ&ۗ#bcUcȟ(7U^LF YBb,IK}UpMdHBeAMrNYOraZ{*zI:ZAЎG^yp}%u:kBH(c\L<;Bٺae 6\u0z\ܸX! rZ'q1ҋ1v}E@rro K,Ot=^ۓ p I'fXQF 2wƶK#]JlVV`PKTpSݢ[P#fYP{N3u]bp&4̕TVx;@j&k L4xWmʱu{ Dʔ"9Dqc(OeP.CIZflZ+3ͼe nlepp'BOE!O6ǾDD7ORlR]7K):Ģ?tT?7鉳MH`[F m.I'5%Ȟ27 AsQі{/R=vh 6.)3oV}Q Hq Ez-y6orP}R)Ӯ£#'ZwJ% {5 6e0CNl-;ٲ)J'hv6QJ'Se'RG >U~wC8oV+WT:A )=x|^]M:+sS)5O!3%]asM{Njl IJWnvZ@͕oY$RkejygpH]r:jq7 (|C&9䱦ZĝK|"W>ytReDZգmWܕofjFCM:=SXUM@Ȟ:91 [ؾ 4.m|~/*/f~8Ie)}gP.î4d@~fw/)Y5_yi_*才c  U9ggWAݪ+OҮ}"6˦2)CR29Oa8F@H g)Xeһ9wA>ڸn.9 ;Z'?KbNHYkPҹl:ʶzہ`u4Ae*=VoAaɦZ;5:t 쿸amJ"UbK=KvܴHn6 S~a WA'q pDuS!Pje2,YN &Ay$ru? 81mBԔ)_ðo=,T5JtNݔ.Iz8a$Cm {+%%0v[i) rh7T52P!ծY3u7SUY2e|!' ]4mIc'guqX/w{Kb : ,⒗;JiMO9gyPAs/3;b${a̤AA H_ &hH“SJ槫k(s/CeBm|9e /iWJԸ!tHWe'<7e-cbYΔ}14oֵei7^:gx$WC/yP|>ŝ optI锴 ߳ST\5)B-!D}z :}B'Ɖ|ȣ.B.T?^W?hzZ8mcWujjQMQ܋]4(11݂eHnG}YW?3mf"nK38 q`P 5<%ϵL6 }WJiQS]J's%#R6y?j8/p c$ah ̮B(@Ⱦہ|#ze..ْۗwbEjnkՖ /·c,}QYnL$LoE|WIܰO%x_609b+ZJC{ T?,읰e{-XpEmԅ!T˂Bو2ʳp#7 :%!$lOęOSG!m~z:7%H5qڨ{k!)]GxQ*N@۟, 濞A^_VP1?:m3+bKꝬR׌x6c?_T?Nu"SFL@k0@皹sFuۮSbA@q6|P l9Α ^6'm\k$]^o_$*uŔTI5X*! L݇!ihD'] 4 kM<۬)w8Z1khLLe 3Օ1Ř~**a !rKD43x}2QN]=a^/hny@@7Qa0uh$ _U( *~ | rOg@f UslFg<00ACp3( D\j%pz M/*;GP Ed)nZ%̀a6J3/~uu"ᦐ>"i@ǜ:xupYo>ĭ7/4:p,ew[bt9/ry}ν"д9283HqЕM9cHoA]m;JmPS|W2s,iefthUUM3O+ @{#z~t2r)D7[) icT CAʹ^ }r"!on d?KMqfT>+x$w Y:Q`sտK|]V;Q. ?vp8S5#N>7"fVƩ &!y jdLM{²}wNX+e/7Gr[FhZ^Xe} /٥8,٠/D_8EGow7qH2zH/#( hmZFRvC[-DȪިm(\O+o؍ zeli>ag9M!rROAĪ:Պ'̸S%D[0/2/C%|kasGyX PXDJGk1S_J,A8 ~%(Bx[bс=xEvF2U-{t6cc#*̥QPF{ع `4~wC '_l/UXlYdڪ9I8ppy3H-wв &~+kٟ+E^xK^Ƚ=ϘWpAH(dH><:~>ŠߍųU~)=jf=Q.R0tY2]p9kgl n'=^lp_6-@5Kt!>MvŮBAț N˒1 'r!e''Y;jqеCc_gE=+ P%˿lX+nnϝo]A5Au 6,Ng7t%]\| ccC_i; 9]OV8EV~kt5.i. ur\)|NB0aiP铯FN==MO{/uh4:rB؄MyF̕Ây^n!|52{v6`W@t)Jl+&bm4 +xxaAx&i/ٲ<,RJSavV뽀X'dOe2XIdJ(}:eрU:)Ļ\tzɊ [OhUW2m%%:̫ U%vWe+0KYc)jatet @ />Ċ#P/P,管f?,Id+3GV[JUgCH|LkaUAc dEx/%_VG_٫xU|l'SiƐN/n WaXe+1$YDlf<>c{Cߞ{L+i/ ^D AOY}fJUo?A&Yt[[>@eĬӑyC~^f|%ժHnPG\BCZ$`8E6ߔa,ɉIJ]ŘUD.l<Շ |f 2N+q䯜/jC/k(5CD#HwP REG~qwf ;w+lkZLH0.#vK}1?cҝZ_1l83 ݨa*02&I]$<cGbFT7 &m%vԟu4,o9/͔%WzԊPesH1]USμyavl{CJӆNmReo„By3?M?j~ϰҒ6v;26|.ĉmS]\ޢ gziac HaDƎ X( D=rw&O{p<f,bfG6gxiYv!ywښѓ]T%mį.}SD}օķAQnP=n_'^=B<#j#὏ɒ!@8L{"31>.Oa{ '`~ù`R 2'pFA%tzwɳ"co}cp9ʾ'G,zXh?HN&Ap,"g!Qm]|?vQ2F %ST|Y1憃GҪt>+rYE&?&;([jZ)* ~C&&B/è)O\nǛIJ*d~*ӁdVG*CX[To:XFKSMr5zPikm'֨UUG[-q4?oj:P2#?kKi4-- (I$TֻP~@,,Pf j˃7zcp'xngM Wwf"u(#NB^#%iDEN ϲQ;Y$dHj-ׂWG7Ή_1 WaA97e;X2܏Rʀf5ɹj--͑fHf}4o|=- wVCRΖ8b^f711`HgkU[1%I%bEht<#/C&{Gџ8 }MJGc WTmA8nB۶"x,7܊NaHh CfL?u^/g>+";h",ʹ"+\e7Ϩ%ԛxos*ɎMNzQ U-r Y]F&i g.<ܬޮ㬏'c.61}6'`tӯ/vE1U6c[7$Ћ 28{ *F Y`c4؜W[\\iuNkx׭|ey< =62 o]~xf?|#$@\!BYLu`Ł[4zwo YwC L4z n:vkqſLV,xptAAI#6h/MJo5X_fX-ӱe~[{',OVѬ',Zޙ^x+ D:QSxTp-i_}ҭ?}8IO[d`U ;Tdu l}VC 2!DhfSL~k4)P0]!uЍ.@BAyʴ$y$xfe.IGB Nj}wPuf&Joۡxal&$fB> t2MM]L";Jx!ﶡx)c38uN1&m7=/myhS<W0N ̈Ċ7izv*_Zzm"cKT/` &~OnD'+78zFQ̩tj[8+CZ$D?;!vEebXݩ=y=[!פE%.^U588BTEZV'@Rb*V(M맻(aul&[G4kNBsu !M:ϱ ]u Ǝ.XCSsȀFAI|W&hVz\ƿNo`9S^j:go3 w9#(>SM2A|`%/耻y=jʇifI6gk]ўO 3w9Yԓ8,,ͅU)qfp8+ĹC]SU]|)e|ib[ g:tU6v}W&޼W WLZ{N[z!+،tbfyꀕ w҅+es5vNzh~$, %P\Fo*OaA$Yד5vym i C[cLŒM$4 qlcge cd=s] 4zخYDg9F ́0$CuN33{t.đ1%Uגʹ)Bfbz3=OSjddMNhB4?3n%O#= -Dt-֤@T_ws>?NYz_?X_ q!h9^z½W!O{2-QdQ>3fn X.6BDH8ٔ2(ɜyAE# 8> f ڜӎboژ4GƐD~D#r.PRo7XhnxsȎeo{7RʙA/*E5+LDebHĖO'1}jT ޑ}5aΓќMh`߻\`E*=j"gGT*Y9shF#[ -=Fjίr=d{rXղ/e:U邦8(fR,x='G~ܒUbQԎbw?!ʖ6Xa|Iʕ|$gc޺nw>iH Pܭyp8BzoRqu%(!8i Ds IEYi ^XJfc棓V?ּrsB*c%Peg'߯TAcK#=6N#"QFSaBX@{Dklsr0@/_@:0$Y CXK]&'!^md9~%N9GtSuW540nd& UJb()bR{NV"}"avAԉ6oCMa(;'O8ly]?gq9 RiXMMwD2Z` Nh.X[iFf* };5/|]@ZTnvb*Mw-o21#V 6wp[H!ʏhf !!/릁r+ ޵W: ciI7=~un+#mi/lݻ"dbx.uoxw:Կc% ܑlјt/1$f 8TP5/+a&]|I4=ҧa9%KYZ˸A3#|>Y 5E0vW Fm"7hDA ^?ƚqaX?.9#fM~ЍECh.HuaJˉ5fo*'H/,kVJ4|@m"]i`rKhy\*I/v<{Q]-P<.*^gw'wiR^[ϱC?[\ᭊ\g%m*c ȪYqT)gc%A"з@m-D \ G:$)a~p#HKBqF~ؑ #,z͉]׵rSs2f9zf Vyl{LN1亇 δI׷hZiSWEpJ! aQ(Ѱfa_ЛPDz.-J.@ofAw7&=W`b#MNH*?] x2 Z;EG+ JIML8rŊCdszJ:)sx̳UڛWtmJfWmx~|TN漮6bHP*dhR; Td+Q=jz 'TK֪gjPNΡcW֢- @ Cjo։ky<¦wq'i]H1cF>tgwH ]x~kY^}OyjOiwowqÉ aP^^ 9 0e&%Ă'-:4Q \榸mD_g~{tD=±a*߫z8=cjrB*m&BЏؚJQ' 8+藫IϥBnbj0E G,}}rS|X^0+nq|OL2>S=]٬ղ{7[ ]E =AT#YKmj$DEBSҔ.~}EX|(&lW)_B)aO RtZ2[Bll x&E~C0iޤ1Cc e^ȱi/2 ,EXR2[= dO|'ܶQ;N;T2ߗ=q[4|G+WQ 6 Ca1aYZF%xJH= ۛ x,#|+]#(֓yE$Z%hXE~T[d[p_~5@;Zuo:HM 2A C3r0{2:85g,EXN?4m`O,-?ڨvus,ەaRòg8",%$qbHeMzl b/w*HCE L[Px+lBsJŵe6Zb=;z"R70jfNm)w: )O4!Zw{WБxVD֣X!U9TeKެfbX*^h qƽi'ސke@NE8" *v`AqJQ\?hXd+"e>un8 Rօb_? 0Uw`End!ٰG&?ΥO +j 2KfK['G`v(U ƕaL0t=ג⬹\crC rBƢvrix śHVy0:J CV'ۍG\!X9o+eCˤzK;WGNNĮP]* X)[ʂ=^?@f֑7~ 5>Tߕ,B{`I|yY&Шm:&Nqųu{Qgp, c pW2Z?gppա\:n{@No&MEtIiՙ ]O[^]TkQaT?+/(&?,_'I][|検gnÅ]=U5zDVJ,GmX$ t8h>ԯZl+nY:pJo9(9ْFegujh`")X{{Թ~('糆UGCqv#^s 9nرHTQYܡQol70ko}8-K.2g\Π( I?sn>]Cy*$dW%6 Whk쉊]Jd/2񎖃5Z:ɂHKsE0;fXWǶ8.]v͈nֹmLaձH_$D)7XXކwu0X"uIS@<#r,Ï&fkzH48VN<<|iMt,zn ]Da gM ʄ֙oT?i)v #!̌G=id6EEUg/^Uh#cۮ\ F'"jngGU[;RbIajnbRcۏV/j00B:W=6-#J/bO9ZU1c1ͬƄM41&BՂ}tワs d͝/t{MV5  MMFiAwP] &B:Qvo@driUpXmb_,q6 q*dJNCPtέ^c`[p}W*&hѡ xÂ.;,Q&_) NQL*5\@i2BvZIR1 e4(uxG-j%ɉ1+t3ƇQвIt^_'T׎_MSLQa0HY[W E!1(!z) B<HnN߶옰ΎY9!ushI?Ʃ!4?wEgt)jԻSplI ǧmʐ4UM}&_}%|B]l$MTz yn]~6_)ڝ6/7uwiyv{-+g =1lkX {#|eHڛ\Nb4YEj˕( u,W.8&"=2l/;epŜ#uDE$?G-> DTH1z].;G8%' yzjQ;Tˉm]lR%~#Q8n>l(My맭$u`U򅽡7s=w!N9AM42|D>?.@%L0~'EBƜFB Yְ_{'#IV} 3s){ q(;k @ڏ]WP}wĬ 6 {;Y6U)`%Hb:möS^C&vzJ;P1C8Tm$Ox>!3u9>FW>oi:]g. J= qp9 j< @YO5&&'cʨ\d`;PxPinxuh|l} ~ٲjI SߒS>7p$pąeNX>^jcxqg ;L$kXs45#M +5ldĴfs҄3z@ 2k5+ad Yd̂)J!??)5CrIFߧb[Fks{C:Mc$M|']7V$yі5#_b܃.ڒ']s E$S;s*HۤJ'P>u/tΏ:]?)W`頎NeRŰZjmvⰯJeԹgKWqz%*9''(NӲR#)O@YGN-WvčZ\d: 91PVg%MA6J.~ Y.J[@ IPL;'\mTA~ (bPg51]ݐq'x$dz4ټ#5n&{ 'Im(:u HW}>v)KMYӇ4H<"[r(88K, 8w`ϤtlrזCI%v/GY5=4 "PQ *,XDAdsrlQJ~f7_<yo3?y$vCËvt1۔I I d\Wtp Z,pѳcPS^bMtŌ10N]Z/Ǧ̏ŭ'#?'L (3TLl.\>Gރ/CJ"MfٛiO-G y0]AGF5y>S'9Ǐu ?Nau\l>HUUN w %*vZ)Ld_ 7TZdsDf~@n" AcSɹT{TÚ]@ZMr N/Z{PE̙t_H.ZXsz$m^xi.<1Ü )owZ buVW7xQI`UljA%m]vMVD5T]'1H"иWN6[d&<&-4ԯ#+ew&oALQ;)β20'o@|7 ]N.]gќ<1deXǗH dJRM8FuF̲0u(4AA(pirb(+ΠXJ?:>ܮP' 4GAغ͇#@QVJTqfg^>ߑw_{:A*$%NYI͆EhY49L] Īsf|dDTxb * V0 (,usC 0h}I9sV}fJ5eWz􍊶6>zz6؜ Vvu;1 ?K`yX67DkS1RNj5~<&~nuwPP@_{3:-wSvW$^1$S7.hr%S&-cɶq h@G B w{ƼHmH $m,5OC 4Ô^U<6X+eb{ ,$jh̲k#_$h̒ aWZ< vMeκ#92i_QƱsV^Y/Kx'?9p.X`]~ʋwTæS,>ZT 8=ӯ(;%{x~ݦG]gY,ܲDpdeުxGg+/؄xGc $t.9W"ػx"7mYHN{B1IyNi,[HI mJeC P ti$2x쪛{6Q󗨗8؜o1ZY3K=uSu&vP@PHFfHGZ(=>~`W˜ζAf{@6ƧNL| )Reb^Vyetڶ/ܒ2kUJfW3ŁVE$l2lS  fur"~*2д[ nܙnVpR^)"ffik]U)9U^[0٥xLH/|?=˓;#| >ȳN&@`}Lۯ>Y)F.B:, x*FSSDKWً>vְ9Z<;]q/>`>vRE؄֮~ShOF-? ԒxQ.Cwב([fl [_B98j.\Q,03VP# F >ND%L7u%_<TKf)5M  xLpߪ25hɹ{<|).`d݈&>O$,J;x] @Ӌ~ 9MxăiTD]84y$DR}[_,#0b7E~d㚼YPWiS u?kTyŰ4CMgSgm^ʷw]P3jLQy1o?͔نo̩&{兾3>fnxsNۑ)T|]XmN{8n5%Itp<ezz)uW,Et-dTCE0gm8{)R2%kh)Ld[& ^nʳyUr_qʄV<1U1ra2TV1XqG{TkN .4[:Jdt/yh,}LBV]m cp8, V^J=\JCٺ[MofM_d}uU7sx^ /FHT], B?E;S׈+K5]_@z%z`BK]PT_ZΒKZ$r}y@w&t3n ĎݨG!uDza2WNܢ٨Hdf8#YԠ>.8H,+4UŘ܌SfoPg_BĐ,)|-Oh1HN5T7莬wuMlN}nnE%⥮>ALheBс^ǃF1#`= l l&ϟ.>%r_=(4DCj-3ԝnfAUBcFqt ;j1p~X=kϯ!h5v^ XD˛|ޗզ1Pޯ,ۀ?crdI'|uрh,,kc: pv1]}@O18Uel6[ OX5Vͺ*1:$XatHٷ1Б)˷oj [ jcJ1gh>.^wgzcT5.;.ϖ bdM/{Z[.By[ 4 [k Pg)#c eԍAORN0H%v3tUoOTic1H0;؂de!HUn2Np c^*q9EjoX3>^o6%g0nfCbM{_=M1.5\q+bem,x(sٗj.$WzqŹݒšeѐ"ZT8(ڣ80RpOE!0˭ v]WJ ~ 8N`9 e鞺 y,W5)2kF)i ̎eRh9mbƕ=k3bAJ5舂Ho1*li?䐨x?uAtBTvN|!3zÁǠ3# C`ZoxG"KLzFPQ /+@+6Z@IosQ^ח,/c!- ҃g_b7!KeIzP?ġW+BY~A?q)G€c)a nq`GS/;kIkƂ+Ǐ2EW:c <0t`#s P\*1^݇w<fdCĭH&fks| 5z"5Co&1B'PoI]{Qd7xtc#&qIԎ6DuE~*F ξ`턷[3*_^n1Zv!_SqCˉҚlQ`&0-E.RIuK'2(^ԺHe2(o85So橄)}ꦌEjaK:l^tQ}a}5jJLnsu(; R c1fs_Їʲ5|8}*ߪH2W7 yw. \&"qAm]d]ZXh"kyj^& LAP2jɛsm̎\޸/_.Ntwd6"VK&LXҖb #⑺7PG2*܃Xo`wt  }7GIjY,qU=10qmnVZI32CU/%=c#/w h:dU ?NҏbY'pG^HYgthgvM_-~jz #^xMhyf^*df>-KmtJ6 4=S ELuW/wg>)Bs|P1ju|2H(Cw]'І9USYL@ )2X*), xO<Dž Yuq<֙TtM`2 aEÌ0aL =Taʶ%9fj,P$AZ4{L .*JLFggLX?)AݳuXt ?>\wIlf`"dꅊDy)<'yI~on6.cwLd֑[t7WHlqk;$Y?`9v67~bUe≠UTPm疗uf7b4la ;x<^>o/Yh 0oi*c\^9[p[GFP3ie\q̤}XT/#)ʽ |D u0^>-[*r/{e8WϹ,} ݄YI=F]"MwP4a޻:,/O >s7ipz_F 7IuoemؿR$an)3>e?%û ʎ8MAWnbgqY.# f<pf2xqde7-U=Ē FV_UARDUx^ 1ՓOE3X)V3%nM0(\&,ՈǦ,DĎuik"q\Ng;%7- 3PZ^X0g!Ւ+TfRlhs.<ۈ'2`_]y_C}L^^jdӯMrPfcw?)(PdQ}OZD_mH#; 5 6N.EU0"R|_4zE2 uB"_ژGG&:Wo$39 CCvDUC-?]Ug| Rڎ y\5MU-~G]v* *dc|9vdZj edj Yiŀh=N-B=mMc0ӡ{QX~P+uAd*-X.o2Dګ ʠ9,z,U^zP}DM[Ar :w('2;"Uqi8eD F R`Pȋ{54̥SXsYyFu}L \전A1Z 1ijr^*adѿLsE1vt JBwV`&cF 'J o69#е ɖy=r5xd<_A#<0^T"ג $稈ylLmwy@'t:a8BBݓ"FgjOP[ 4>5>c6^-э6;jI1o|t㺸t] $إyrڤG$'}Jn*s.0pqSuh o9s /z/j@Q/;H \Ȏ; J3C+3wWT8%Q&S(Ri&z/n^un!U?X6:Fd,HNY@c i{^>BɂYؕ_jQM0!U͡tZSt@wei1ɒN+_?Nى ="+Dr> ok<&E*e+^eE Ӗv;l/ᡇ*]yR8KoȽۃ#nqWd~,5vEhюQX*6'ڪ鴻neekӉP)d<7*.oyLj"v#iy:g{1ޗ ]s t0 l9ADbB8~/P$Ϡ&L)0V/b(<-7pGMmvYL!]FNŞ`ӷ$hQ=;k򾾱RRt-^C`x[uА *M.G=F{WDt? U_G"Ei ļ"RKشhSkds%o@OY5ɫ}&Nm;mQ%H]MeηUܑyB=*{6h)J.'LJy\SK}O_a{uYhKc:20SF|;S[LMʐ,a e5WF:L@d9:c%pB/~BgSNDc)4fLƊ79妦j!Ad\XH,am<|))Q10f!i(f=rV&j+$]ۜrJ(_F0SY1mV $kscos,lc Qkg:}G,.`~hYmVlvV E.3Q^]}\9P%][EQ8jf?"g"+tDž4i3}8\~Y^wRJt):! {Y=߀$% PNY<fhlZ&b%ĉbXUjl.f)!%ro|Ò2s YQB 3vqq)IٞR5#yNJ,ˌxK'j_ڻ0L TIz<ݙ-{^K]J UW;E;Q'kpOv2 Qɂ]_HW]ea${^7똉~_avr@"κKvr~~z{sж[m&Gc ntCyby) TSli1_!}nVn+@۱* wkGj}" 'Mxc[i }HW^ jY5wlno, MX3pwדUMcv^zMƇc0U -I0持[f ;JX.`cK{R..$Yh l@׶P=$ C\&^M նr!~Xyll)tq4I=6,6]O|+Ή kL}:6x6sF F%9՞U#P"n(sp{](!VkU!l:_VTQ^tBit/ ~WNhtB/*9˘S,q㜉P.MдIDMolIo&iљ DTY9]A$"L咀W|SbI"lR$}2{gvܖX*Cp9\ :z}aPQ.[{]+`Wc,NmIejdrJ!4DC>p.q[i)G}N<2<9Ls ;e=ǸzˆP"Z8A,b,;fHUtOHKAcY9VzM8rs.A:fg~r-S6HPA{i]Wv7r"UC07쏢,愶ucY!NU@ڇ;i1 p$_={tGc/Ȋ0yn8=) ]aT,%%68VYCBI8k$Q Q.¢ՅmG!M|t;o h(wh-+o ])$5\p-hs/@ǫbY^0K?`uOMl *N:sA?Y4u]#bȴ줖gH+$ l.73ZuG~<'>Qyr󎲖&أ#`A֭.ݟQ ҈-FŮ]ڽ]t^ᖃ9͌$$aXV;|&cD,,aU0Y$t8`8Ӹ|2A8% YAsGrRKFXy9:9A壡dkhzfE4CEr R,,XZI[4ހ56t:q:Vx+)K Y)u6qXN60 X34|c*U'=̺ o-zE,@l\c-J\zwE]KM6>Fa} :}Ǒѽ IYsb !-@'g῕ Xa *s#"V-ArɔsAo l5('KlugA&"ޢ8f+8M0Z]K\R0nq :z$ .0)-\=%}^3Տì"~q)W # yp dѼd0_ԃ WO48EYJ4@#H*ptd6˳ X (Qg;^cw@E1 ɋTɜ}"ԒIj|#Gqfx? 얈Pͯ<$Ю~1yZxǿэ(' }p*V~_ a w"%:!\QT;sTd`B@KҒG]S&,A\ u:Qag{}@_|V0P0@5ZMըo7?]ObSx*=IE]\i8 ~$Q̃)g%A %v@u fo.JwC-'Mjp.)N;0ֵGfND͢wP=`Nw7O','?+fu%mM{-9=lMOek 5!d|F@a Y**l6YwFe 7M  [Uv%{‡[_ȑgZ7]fk֘ p9pmbf$v!N结tqCX(H G|;cSGR^~G\H5;DW_\i\#nVw8kUh` 3=$44D㸙.aO\gs>fhA3~V!qޜ&߻24$nzh Cg=S2:uPk?g\S#l?njSoC2W0lbbٛftX(}WU#} gw%!'YԤ_x*wdY:y%=Ɲơ]K!ݺϭoȇG똖RN_aGK  #Y@y|(֏r5)j^6$$.#<>c}BR" *k{7I8* |r_#0ZIS'RF9t3[Ml_$|h F$K N A%cgY+[uѷyJu`V0kbRP C@ 7d8 5[X+{^{# /ȱcaq7k̍aWC;4@ ]iWGL0t>49Vr4`C|v=,T`E N-jPVps,[J>uTN{5Gj4n]}FNjuLM1y,d` IIbGDH;ѡlR19 { >LKR]`S|1[Af[bslKJvHJԾ5punۯE;H$1U5~m"<D/ 'AxVRor p>I{k| TZkZ5 -2P?L rdŇtQ QPUrx9hCW t!T[я@HacgeZ2t=ӆV6+h.y%i(gᩰ'T\vծnǺsQ'JYNn X/g.<*) a9@:UOљ740㍟\UI[irTZ){Щ3Лb:MUϾl '9#ڱ7'!d"tNoJcۜpOZ>#/1e%hůxsɠ5v0#^j*lRD\6b! : u`tn~xMP1hRosXjaBD[Hj-K]Tss]Iޕ6Hr#n; h5Mhe ~}hg6/9xjTq/nd'O+j7{Z-@#!> 0Ҁ9 3}*EeN0Ziʊ\Ib`'~uu(Ο_iޱ7 BWǡ\VGz3-eCHIx4^l)CRG+ɷŧea*MՇɡc}'ceQ,fAb;R,+؎M$Yz>_F^OHOiKʏwNNIwlf ©-`'Gw/oZ`Iff)'6,}x : ;&^4 b&_UP키ph}.fPKRK(/.Uw#Ԟ+^4ĺ-I $l7ׅqsl֋,%L&h"8wPTv(<'w_g] 1tsIXcr K_J;{mA9Zo{vd1's,@߀ɳ6&h[ƭkp"Yb"f fsZp=G+ϸ4J@9G4%+(F P@'BC[JD4bךdbuXZ qiK02/4Xh3pJS<{nD}XȺww@ cFV$'\H&쏨]~8[kqM@NW ^Ôdm'38t۟s&l O_nb<ry[I(68]=18 \ i76fx:6BūxwCjVa:9fjطҐ+ͦ:k/2gBD\ JfzԫUw( \/#‹ ]@o_js7eWa!f]4EY0j@~xpHDU!sXW~Y̞'Lw{SCO0+?ST\ҙ7iۦb|+Љ,BTKUZ]YnvnԷ59V {H|qnB])Vy4FO'o"mzc,9iLXmw *Ӓ崞P_n*,hJ d`'$-%{xd~M+rxn)vC:%*x[JǤBA`nD3Mj: 笺UsA7qqf'wI8(27nVR4r,BrÈ?o`Li,kTŹ SHX,`,PaIt/Or2{y;wU,Լe+4:l;,~­ã 6n4 "*8Vc2e]|קTvS~5϶w.H x@DZ ل;̟ZxvQZUN!TC+Y0""΅h}2 U⑸ll,UlMQ-6k _ Ǻ,Pb'.VR;x0(W/c`sތpHKP沓̦E% Q̈́Tzkl| _}&~{IvHuQŲU Дjm98$(%2f*NJ٘hWWRt]]`xE&7eV))H뼨+G8gՄղQ+Fk fZ ^#23TdcwY vK9[3j%@%4C{Y/ҕh)ÊPҎstR!Kxpقo~dE r}O)VWU*b[ueQjwzxBհQrJDҰt'Cut^nM_P .Zg_/'bg] +P,sX[$ت9u37)$;*3q)D֭4|[gOx0d~*ouK 3,ƹ{wB4˜+H g&EB_ b_t T^ O5#o@TKuޜ:XLhrML f ff1qGgo'+@~MU-;bkMkSQV:n1\5ľޙŘ*5SJae噂LC6|X7dP( *r ټFtQvɣ';P 5`#/ .op1:g%{c"&c ŧbw,i",FMN;/س4P&jJ:.j-uU@cpC%%;N1;_t+0z5hAK>WVmS&q}XjOfCpߡgX/) V]VW V|$Ώ&d%,.ᐑPU-sNSZ,?@4 PNB$w-cty4 ӧc z|)4[sRfιѱ!ymuԢ[[Ek!ڏ_XpCN : }.,ƀٯaJ?Ƚ>Vek!MTh #ۤa6Ll:ι'M9Jȗ~y΢oēJxcHA\5Md,#%#1%~_2M`IW  jO@(6~| |tL% N} ʦ ـ%>:EbLLY{jc)<f8ۀo_a3CNFKઋm5FC b"p FBuXu%ľUH_OЂh;zBu2JqZ$ Zg]r8J*Xz7Ω*(μzPi&>KG&ɒ@ތBS ˺*=Xq 2b68dRKޯ.$` 1٘}g67t@Gy*) VC0eO&q,/ .mzΆ*rƽ=vq\V .Zaɕ 0SE*y\ \M>n54(C0;E_Ob~8YWL+t*y`w(8:yyB*}h_ِfK;dU~+=İ*0;ׅᡀ՞5aIxS;h"z^Ԟ&tL.B|uPdu7t"*]هW0/Hǣ>kgH4et%Xm:@iugM1Q=N"plY[MoݩU^"iiX6WV?a;j%( a =C4QR{YZbj7ɓ[Kʻ~-WA)q9G*);ˣL1Le SfMuGM;" \?ehsuSd5^PҶCpxdW$Mn)_R1=sX:+D֐ˆ""u 4P}5@W#^UDv;2sҢԭaIA>>,pSP`: jrAͽ2}>l9dnP\X`֟c.b=d׫7*XlF_q@ݪ6zd r5E0WOj6+ZG9(֫)+&Hx<>3As.?1㺐m q:֋u*|NAK.X) (Co$`pnG ??r}LIjrw[k VscEQS֚b)\J:Yv3BS5䈓_\s?&::ϣ9z֚X*|rm/:E6W~GуIK*+X475'O%Q~ds{҅>PÈnX9u+k/N3Td0sV.vۍjSB,ޞnjJe{'ti \Yٜ]@ =98 D@4N_v'-yn8#B%÷ת Ax6^L#@HG'Iͫ_yBV3:%5 @ bԩDV٨,QlT%dΣ{I:fn4{vUdQ9< OclMahz[w`f$Ul0ca6u!emt$v`skdrk.Pd㮳ͥ>P{fVԅ10uC2A Яpn6+g= {V)jaο[6S˦@ mpx{},5f@}%+oWimQRV$GQy)d wIoR&Ḱ.%ό)8z m44k䀻5Cyq_}^eW~<5ʡ ,;o^ۖ5%pڕx5T̾ܜI/%4DF#tv Ϸ$}oe I4B.~Ώ~/{-Yp{\O]zq2+RYR^f<" tyб!|=:;خ7 A1M7 x_OdVڍƚPJ^mv=TMuإ‚nӀ{&?J1WV?]|('fni%aw-8>>Zd]*a$.HooI1#PӶh G9Xws@䀸+|dž?{YhGsV~p>W52Qh2N/b3ngSMykNԇhQ&ʧy욇}McѮLb-49 ޣɚ ݬj`>˵3:Ρ=4NUr6I{<`,*fIN& 3PiǑz>+rc{215L1geQ-nk} sA^bX}I1%aN j2(O8.ϑ85TfiLDw˥bh{TĮdk?0Dʓ{Xpr3ͱ)>b7>t I,+f|m EiffʕQ8y! !kT 83kȥRI f/ԃ.@ʽ *~8L39e7#T`93+gEaD.RJFEm2iގ8XւAnv\W* k?ƺh#{pRՕ?]v,WI9D8%%\˽*J93~GH{f@1mJ{nb-nafło39XQBm4[I9i=&kGkj[)1d){⼜LpC~ ,Dxae%/#ܡk">P(ESaL} pȚ(Y RmŬnԿhIJ6(g=>$$BQԖ >T\*WS!e-5ā-"qvL1m6ѕ(/Co/OTLd^ 6EbfYftM [K)Nzι ak=k ;' +0zP%f,[gT2]̹*Q[VG%q{m@28Ծ`BJ4eeMwcҲ CKy.s҅vC ezYm$HKC8Ř{59~b`\x[ }˩ $B՘yk'rq :]Cȍ_uiV}장ˎmhfy~\ n8\g{WJqF25Dsm2\Vxq?IGY ,_ L߈QU8}z;C?9Ǹ=?D(0TҸMp+Tl!cV`17,K;1 [߲0z&ʷOnU^PC0Ut 8Y\4L4v"|Na`N(=zGe` &ǟtÔsc̷lkhjڲ%)WX,ч;{ ]W5Ze*1UXHBl66mXd~76Gz6Z5=4R'4ۣZ߯Ue{^_}8>Y?ϒK]N)$` sV,x?Z\Ü_X.Y=S`jJ%]R֖<»GY,n`SA1Nl& 0jfQ5sbc0/qCQN)ПXp/9]c0s 3/H⌷rYXݿ>EV-^Nn0-`"zTGt:MW ZxV0wi 28NAz0޵pDZ~hݔ(%ʯ;x㰷j/.PF(w.Gg?E ~6{;UI~QڥV#dluC \rHVa_ruh,]Jߴ]r(j/a ]oΆCo|V3-{iȮz:ν!w1z `ixo\+c#h翚Dh=qm:5I8}ETu\6 b=z1cH׮e4P]GHb3a>zJB NfKIC?U ͋ 0LsաpB$;Oz\R?82"k"0j Xq;޸Qr9Wl(\TnfLWA!. .B4s&^6mu:=h&6T*\rndH3M^8.ph,~shPorVu\#; p[DٷN}E$l2uGnNM3U[|G7S}k<52;iy1} ]Ud%8-,(84a =!co csԋ~G0 gf/CQռާbMLu16PG/ADJ^&qGUXeX>fQa!=Mz݁L14mDj"ڛr7ܧr[k%2DZ9_y&Ŕ?o-hq-k`$ dNB/-THr'(eml"€u`)cSpkTuz]{ym?r5,dp $X!ϒ]).FvNE샤Y;y`՝hXŵ U D)+2~RBnm/-𠻖\;r!#'u)bjӪJ)5&g&AݣSԽYIo n Q"K!U+}QtA$j|>O$|LT\aRzſzVX3L}EmkBO68%AJ+_P䁍d"g x ]FzM P ZUZeꦗ_x1D?zr6*{|ii}j::3 N<ܷlʦZq#1E֧$ߥUSg{W9tv_h8!Ki [J\]i}W_!}s6`ŀ]cYɵQiGl쨼ur.C?Sʧ9U3YʢWfN`7[UW6Urb1(exv;30~I %ԗƘ_jw2MQyqoFfgV`0?@Ϲ˸t{?!6n@#.d 2?Y`Ň]]NjPn-D8#SW W/ \a\{ T>b3V!}SJΡgaJ.ORM85L 4bN`ȗ⏞\Qft"2Bpl9V+z+}UOݭ`%pn*W7%W3' IҤ*=;tvJ#r81f63E.9MDґS}_T%G^V?>4ىXeжSiZ]OH̀ŀNMK _};f -KnRP@x7[h5凃), م|K.k kdw'ȕj3 4w`zB6p G+wO {Y} >7\)>i7PN왨K2M -m]#>LHm|X_;r߇΅}zl¹SD(ړ{RvEpԷ'ZX832Y`29=t (Z7:0m.fVaRIK;)uzॎ`"-9,% Qjaai G7 HH:E_eK&mbB̉:u`߁1i;fxֿ)9V)Yހ^a0p_; hGJq(;(R⌆Haء(1٠3|vώxQY^P]J¿a! ⑬ןH2Х 4FQ5T6v'*aۆeEC (ƷcG"Җ^vRQek/̰~6?7nOdUyteqՑNpgl49Y:YzPVC5S}DkJn'ETZi)F_ ezg#= ⷕ@|9 jh <N~4"Œs>L Td4opaMj+Հ݋]}5Ncgt~_g`٭7^Luʠnyi~EpċH5;k,ss#Ƶd7,oCU>vo MďG><+!*.iͤdp߷# 6+v7؜RYԽ6 ,Jg+,=XE眰 tyeUX)ZZ,o^/Hw2)r, CY@dls;aC}6D^ub*/Ij7ը[v!bDIo$DDj`o j)_os\<4OT1WcMy3 ];}klU)77G}D:8]k櫆Xvk6I? ]Hc(5 n2}׵0j)BY%N3&3{Ci,R?VҔQm3Х!YP;Y =A:K@׻ nBILߵ,w;ҿsq[Ewf7jM~QDS2n\8yY*$֕PJ*z27J.ę{^?:D93$"'E)TαBт?A(Kn v61Ǻt&OKC5%+.3r4▵M4(׾)9鸱fc \07>:Qtchj.pV  u{IJv>H2OLi 8,%)s/Wѱ'1 $v $oBɰMDXN2)"#bx C~ӤVwL%ͳlu%Z4)2buP~Zz^%">ِ!Uи; Kki4F-,0Ⱥlʽ&9c)#|ʦq#+;z#e+x_ l{i64myJ 4Rүi31ljLjQm嵬6!^*S{Ԫ"G%`CH^c‚`~XZ ޜ4 1ᨓFlz.u K(0Ƭr.x%NYZ<")βBK;.thsµ\RӃ)? !yN[4$a.WV3IkG=y"vWwH[E\8ba nӣO+TLf-`Lh۫^tx%0UJphJS.PP[9S2w}P}jGg[]4.Bz;7ZWDoճjb1XWc7#6wײ8r|=8@/҅l.ݴ(@!|C8Q N[VK,#&}+\3*Zf:?x(Xh۟Km>I?S&l¹S%)+1v v=^5 @=j\4u0! \ ՞ JTl$r@.tf](%D͊C2nd9?hi_:(VqmScA+𝳺#UJ#yܬaH?uu42=RxcÐ5T wٓZN̤z$>#6xyLIaʹ*ޖ㮶L{7^1 8D%w<@q&_TY;9gYCpq4#m7һ;].|q.cS>>•^i;뛉Pg-3UtE0nu-/<|U y'5@^2#b, x KH;D_#W$áR#;m7čl4Jt|M$q@~.QLvE* ǎh+݈INr܌vH=~U"HO7J}jO VQ:!`{z}]RDGaJ 3ktH`i+~zY%#{f4EmZVK8et%Iy>pC&y:(a2O߀al/|"f}F:ZPW5c.-}SN(Bb /CJ7c}bB/sNL3鵝_%e:p l!F{>GK6l`\jKRF9@L^SThgDBG7 "RoCV=")?`SCk5CxBJ Ɠ?-2rOdu{ob%=b< zc? D͔d&T3`oG%8f>fbP颡mǢu/@x)F+úUN6Gja9M`,gcWs))XU9e1x rOP!8Pwў%FcMCvs Wpbh]CiKEĄ#hI႘F>@>6393e*҂xԠաRYa4`M<6 ]C+(ђ:WHJdɴ&gys#&a}'WaNB?B%aZ?RFk&7<il @Eni NOhbqOe &@GS]N=;-*f5e &Ř"F$\wݜ:yhZ-"I—Dj*hmI289BM^8joj֤ 8f2@JT`qg# J#LZ5 =J,[0lOP1-D|`|Oa9UPP5hu5 m|ĶaM]l0mq HcdEO#|GԊIӄ.CVu'(wj4K$} rr됻uR6W'xBqft-HsEWf]:终v~Tv+cE4Lqj'n)Zc(oY`l QRPgEt z +Ux]GiA絤POtdrD. Z-'JW [m{ӡ5Wt#''.SK^P)v7D{Wš]}1sΘtotݚ. D]ieDR:hA1٬k7M{6K^Kܡ)B>UK͡XVI͂;C9MF`gqi;Wۉ]!,Xy[dI O()jG5Jjׯ,,yqyNUy"]<"@9Ē*@p8nPCd XƧ/GmWK)Kǁf?H9=m2U#[ӻuYiR'5qtݛk8,aZN@֘2LęA^ySФ7\p6ӔQ C|хasaC"q?[0F2  @j'3 4!ΫL8@TV%|29_1tL/. ;=] cO}1¤DW@EH͆-/RYClUrkot0:6F6}r P߄߯ڝqAdWG`LbF3.7J 6 nf+!5\Ȃc3*?F奂x5aIGruCC˥+a^0R?deKg.CBxx/gʫ㡼pƽUiLǟs~V.~|p` s;0iY9VIQNsԹq1nGMɣF ᰀÌ) M{sywKHi>K?ᆶC} *8Dl[Χ*f |?齸}5iBs}XШQaM10Ǩo&Fցc(3ZȂa}x$@ZACR<@ʁ;J^2ø~QF,/HEAe#I3%e>Zc]+M6H PV,`zc,k` KzFnJMeo2ӛjEa7"MNϲg^ءZN<4ɜB+ DS6xl܆t)).YbGQ'7ssLY[4 !AVc co#YS06 mxQ{ռiEX6Yo'U60SD5AttwdKk|TC-cQHd )V)Z߬Aa(ȄLO`*͌((%P폽=ß"$۸ޯ1y++^ɌR% 5'dT\FNt"tΟZϧa'iAޥ֠=)P5 G;Z2Kc\~ڟb\1+pGp;Zt|/ں \#cujҪڋ7bOߌ(!.cX\˳2R`a T`È5sRO1.Tm#=? à55 ue[m[~͹1hT]g WZzT$8ȇl*aŔTg~V,j\Xt$J1(UQqB*yهΫL,ytްNFlDܮ}zF#{F⛡b%1D9DŽ1iny1W)AӞ{s%.T@Ol J Eq1gZu㋉Jo%]No{e3j/&T'ӰM$[7GQ5ȂE4vĘAc΄joF =^ $0Fσpv 'L'1IWA@8dyW/6zI: "uA bJ^)ę/`w3,YE@$>znkgn4Kj,%i,)45WږS^$T`ާcsLhOpHgDY_Ҥlq?C5n_)=R}MagqrqVwZu,6yWFcOm.$srX- c霢[jRv#.& /n&2cƘU_( Hb`H׋ܪf1dYQ̰t9gv^7)_{3Iid{TX֚SC'QEQߪ Sc߈h]a<|L+Ba^Ԯ<NnvqWU`%yvo[+{\1얾rn+jP*v"n3,'>;\w{MԚD 2ӾΎxIiCņKCB`}I0`X69O9Q:n8chG]vZfaD6nF!Z o,R4NQOv%]YϚ-Dixyۙw M`BOk"/fP튶 z3ZDؖ yA)!>_03XRuODPCb2]/ i¤dԹϻ Ɯ[;uտ6!B ϙSs͍U,bٱѫv'!Xw"3}4,%%{eq^;fd(:Ί2ȻSh`ГS&9X6߮1' i(_!s$|)C#Ϛ>.w:;Gu[}&I7젉}]M6(k2S5xUִ/fUr]G AP,;eY|2[9&Ղ>]_Žc#"451Ozz;yn$%ҫ'( $'MN>jV8p^m}1 2+IגkTJt t2Kׄ$Mg*=r&RBa[ D9OCJrmkQ"ݵ'6[( ȐiWxGT= &$G9[a> 8mSKp?i7 hףn-<+Okaݴb pӄNȢtxYVyrޯSJ5J剉3BQ6/ՙ;;qB4,>S>D]m b9o9_̰6s,%`oFh] f`Ux<|Nӫ @V=f@ ]g˼ &_o%ҶA^<slVtmo|nGñ~BLmcն{灜׉'7;e$p\ivgO,-3ÿSjn%Qнx%pF{^ƺmvOL- C>y0E3K 7?ng[vX2> zyzqpF,8K ]L]$rʪe0+ Bfě2w&o`_A)01\+/ϋR*mk}wc$DՒ+?9ǙA='4EV2Jy=>o`zI6 wQв̡8H0Y:>qx70g?>itK^@fϝDQ`[q`WoDm*.6!5NGt:Ő]\(AJ#o?1 X徒C]K%sv*}| +HByVL/NPTözs-13Lyn56%ot/{c.;2ًg#*p Sڟ/_4Lt\+[Qꯔz!ʒ !_P[*WyZ hV ]=SߴY8~kp_a6djl96l}-܆\ILd߶;4S@Dc/q[V#'`3=rG)+=8?s[uNd\V%FD1T}݋n߆boA>C5C +HMaNBE|%D Z#܏mc6pG;;2eGrZٔ\ _һH/Ěs!wEi >YUA0 )͠`B֏ʗUL׬M+M"]p?j ^'|5雃 NM&:ؗ3G g>-OXϻ:N ns<;:] ޮʆU%&5E"_x[ͦҀ64cr Ch4 rh##l6|26a c{ hye2Yќ\ N(཭X-} Î?yY8TwNK;eGZcJqU_p ڴ8"g}K7s FkfY䲳zZ % Zx׳éQBg)tڸ!gQqYaZ8Bf ]aO.I; ݯ(~PxOMs&{lMպ| C ;GqG[.h/AK[_ TA!q," ~rI_>KZ$&4dɕ_=gRKâ FFPTk4 Yƕ7_96)K3'n (c6/_x9GkɁqӶW_XiWW$2o Ct/?j_bC*30햾K3Á4zIti$TuTAG@v8ICDb mx gX%]k5P47 <~ީD'چԚ\)K7H_huU/j 1_+)PG|9Xb/ +-Վ WhťiJCV~˃n"*A&D;b.[T\\a"2ҿ`^ȏib ,)4u lZf!i%e%_R Y >t䩋*J-f_![ rfy\.Z=)jUGa=C>H-5d#?2Hm6YV-s=v38C&:w]r>O0$u97A^I7' ޳\eUim' pd$*!Ėٲ1IH5T; El};YiaKH4s~bC%`[Y!W:mw~/L>%q9̦j_whpS&5 o3=(GuRn"9_MvaG]q<ٍܿwJ?aRӁ<րbp B"ÛwkF F?1rhmQ韶F#2Qb8}k:$ƫK`Zz4A)JUt/;"JjQ1Lq͛8SUB: ,y}>W͊нm.^}icԣ_A}&%B"?h .=r')qHc>g;l@61-*`}G6Kx q WGF8Jdϐ{8K{hStר&Kn_ 6aqet.V_h0o@nODJtnR4_p]86b5~vDX,&G؄ٓ-K7,&$Ru$ihtVDhaApisO/ k}Li8 V\s@FU8:]sxk601$;{U?~96A0HJ6cK0Ԯ*"3W FĂK=g$L{urS䭣wea t&) "ZkqP&2VdX¥8o- L_TwsG TauZ j_)lq\>/(;]ò\7946?< ~o_"k'- z! H.cE|)9wPk񕓱c9 ?¹]m{(<{rJk75-.GN&QIixfRBWy~&s^mR/@\k0Z"cJͪWw ͺ!|1IIۯ=oHu1f9?{hdڛ+[9d-R{MkJ-xJ.&+*Scn?7qVXsK)\uܣ4D8_Y&Rɂ'ƨYʌm+o푏G69E{M݌y8ٝYzu(dx1  hUS!ލ 1l=|JPر <[g^]=H:6;]G؀,(;@~<\!JFza4P &'_n3mYW8.q|v |ӯc7 ?x%``",YsuV3HU6Z˸]P4fїln8?0CqCUކ';{l絬6-`lxTлLrT )c }Ұm3fFmN灆"r~ 6AB@eӋo4H37;%9ZY7P{UvJYɻO\Sq>SIw2 vDwQ@pTDP#ځ%}.iPNRȍVr7=J,7`z^a6'1[iZ޹[u[$cOc԰>+KB"fүnJ %r-ތmav'.٦2ȚCtf},R ~tfL;q i:giUa5]>pԩٙ<+uul_LuBV b5J0Kdtpڽo,;pG,uA[x\菌%X(+? >Ğ7]X=5^{',n B@HmYE;xWw5C|H\kۢn)'.1U a&b3kQd Ju#H]!Zo[G2[a& D PiV8a|Gdځ/?J  2E@i:%m,0QJI26x8b| ԳY >XSXOSevUQʨНM?DG.5Jߝ~%'$(.ҺHcvX'"ySaOJbG@>}c_3$pĤ$c^z[tTLHcl );m)x4J1@7gwT_R lg\Wuׂ22\MeBbb{]/"€8uvq?$'r ҁZm*䪭$!k9PCBƘ=H&I3PEK7VXڌRU\2RC1N5EZ3Q*+Ct,}Bu՗.Vrew2 <]bTZ''o~IWJCuv[ Y*xJ}֫~Lhøj10? \E `z.mep `*@>6([YmsD7x0YZђ>ЩmsHywiMKd,pyZ#w&+B|#_߸NLQlbbyh8K~c>w1+i QmTAY5=y:e$]܍~7pDubpilJ1Uw )~mߑZCdh)ѥS5ǘв喕mΪpl=Wk<=v@!i7Vd>f0 )/ۨy8x -)sZy æxXlowm$w.0ӽ,l{E0vPvZmٕ@68 u7O,ߙ[f.#݉< `Q{nᆞ>_5!R|,/CiukPc(% Ʉ5SXƳ9\7( R4_B,]NK@ڦXz/fj.l #Ŏ5CMY'4ٰZSW(N/꧈H ,Oa ; /L A%^1Ƒ= b0ts_+@H8Qо,U c-Y]0c-@7m±DCv7:RxU8xJ5]Sc2 A.2oO=):N_zWyq&j (^K ``Pe(h~y\`K|k?1ey ~u>66SF0  %q'ܪ\,+ڹρـ2,ibNC0 b$NK=8Hi׺޺[oUF)4Vy;_DO j(ftER"Oaؚc&(_ 5R߰"眃YC;ΎWس 0Gr0 `_CIEݤD6[C= T$X[EيߌݻѺ'vNiӆBNyu|+$I",* HG- =A8ixɝoC1v"IÄL'`˥+uJa`vk{~9ڽب)obȢk`cB-KI(X|RvLWpO'z)9I՗uʶXC# )^#\^Rk:}]TqqcN.J4gxp,%y&7w2$.ЃX%>f Ar$o.>R.V~nX>S}ʖbǦrSQ, aVYˁy٦0-vzk^}6;n.`:6ouN уCOt 4*чF^Ostk ~h瑬`=WLfp4ڕp{(J<q?ڊ q>|yo9v1:X/ׯi6Q4DzFtTF7&aI ?StfM)ct>Цdjd/lP4:W1!|e|uY-!F&,T-s<4=|WjC #Y8]vcoCd4 5howgWN 7LvFd K!BMիphtyDsF#ҚH˯.M-!4O2YY*=%rHJ* , Q4ؾ݈I$D4x8fB;{(ɋ7*u;Y5I[x:.吰k,6w$/<04 gwJ =Kr|4:W>v Yt6Bszb[:Iw׵F/$2Z3Dғt%ck1ƥNBԴctO jy~e`{@Yvb^Ux /(by6xs,[ u1@V2u _UW-?،ƅ 2@@YE+ݒt7/#b ߺ ؾb }VCSApM(cO,{Ukn^E1)Bhl(e]: n28\\p[Q9we˹ 6#Ij+>^ά؀AE ǝA4R D-*&V-SH{VVyWHM'w-ʅim63ŤRH C4'/՘!TZWDfce^oS+yR{yL!f(J|jM&h*KaZp٦χq]ƋJUݑkz5}qL#gԌLRP&7 潁^3I' Y2VQg [wLT40qȂd_7< $4[QԜ4hQn;DnkI>Dlh*m}r\,: ďtp𹅔] πwbfм#Y^QTcCXz{%vZ>mXHA'EU=&⒇ܩ saA^/] c~kt1Fj"HG1/}(FTQwn ~q&\ w@5F(QuyxsY ҴYEd.!=)}~x7AztWz[6:H5H )i:W7tŖ‘1ŝJ"gH*_8E<&> Ŧ)?ݷ!j}R(h GMZ#e3O3nW%znjlׅ.񫲂)Mܽ7D508ԋqgVԄ{B,?Sػ`E{4a^Te^x06PaũO}k`#} )B2ahĬ* A"1&Sε6RgȈ}MS?m*w0v'*u.ÅE PPn1o⹾pO3/kSy!B/!(T0T79W+-z^U @h1+!U\: ;ݬ1e1vj*| g   8=p݋j17FE* W7߫\Vӭę[VT\<闚 ЯwTYjd:dLBsBա땪[DнCTRp6Fp.k@ɔdOlms%H^lkݘ2X=Qt GUiB7B^*a؇!Ibem7Wi}z]ZkZ>qkY5Z\\܌y>5Kd# )]dݤKfgWrSNb&0(`Fg-n@i.旃cZٵz |"#<+2ӅC=C.+v%os[aMNi.,U2ov) Dz(p}!Y]Ȋ1gaQ>Hs|^Dzr)CWMkSԀF+A(4nIC 3IUƖO9Mݳ} Xr>I[|adQ {sO?a9 sX@݁a%oV& Sy1}D˚ʜA`Rm?nŊ8hlNA<)wqH`l2L0q}&ejX\lX)T_SoNZSe[C\79"w`dKϷZ0cgh(HgZn =ae)Nܘ1|Î:0Ae\h43MD.1>d\opZe =(^Ar6ˇ/F~$@|*g)&enLG&Yg:.'(aYuC'kDPozUwY@PwwIlV*H( R(W0l#<G7`ꀳL%[i- bq0fP%7i4IfVx__/KQbv59cTt3Q!B`'oRI0w'+jYǐ} Xn %xз==dyX{ed쫟OO{]!y$ #h d N4mP f:~d(Q? &7ɖz/r5!L|nR 0Un"<K8x&Ze7)r' u&՛!w-qڼ~(uۻk!H?~U߉눎VzVM7xoO;JZЗGl{7fq}C /hh%E ps<#8sr0ii&BϠaGq5_o^J,,ϥ>>`6&.aDkI -(!%V&ôr>E確$u}j0es mcVkL=DJ*R! +׉Sy` v,$7MUe_Ob940-3܋US Jb69yCja?h?v'q[,׾"XTCO4aڗl_s>E8~OrL=5 ,~4(A%֩[1׺A92,DWm׳ %#Q*F6|u{ *RG|# l^Y Z "]Ӆݕ}PJh@uF?+z(B+l2 b:Ovh;Gи|Q~.^([qwzԛI9[$TqPBNy'@. =+`o-\{=+20l,I_SRAzgO7HhZ,zRW U Eۅ'iY3oNkd2O=~9~0dX z< CMqx :8N0yv(e8U\72 mv% \J ̒Qtl~Qn.Bl Y([U^xn3~0N"% H$ ^h jep(wu/Come]Yp88ܮnX<"9C. k͇@|(N#~Rg`{deYzjj8V!ރg+# BfmSICڣIˍ}]9LELLZ`p؞BÓŽY'YHR:;|4 acWz%TaU\E mH+d8 ^&%07#'ɉUm%3ꄱyTƜF}*lJx&LEKLYrj_`~l_p!Xġ[ i,yu|7le3pOxlBC'`rw@)VX*:d `N*\Mr+0ljU"RG%i᝹4W4ohR RRŭ/5)WźU5AQPU/ҟ%`U2gO ڏX#@2x< F$AYte%x6٥ƕs\!G՘aqnUXbmLۏ0zSD'IH=UͶ~E=b}෣y8=@ƹyTLu6K$e˅2E|e]=fkFm5r˦el{b]6牻)8fGľiPsV avi3۽QQML|$UT 4d$H% 9e*s.T@<ټ%fc5"!~dĞV f8IG2ř|Goɰӎyo:#*Z)^ѱQ4,*!Nh-<F,!>\Y4;ؿa$޴mU["@JpiƳڜAH/얆.c&(;0C`Ӯ#nkHآ p &'z&G STO֊险+̬/LMXrp)󢎚] CgMOR01~7j +e~Yy1:d[Xc.t}VeCOҿ62zq.H'|T Dg>+醚 ju g\翟`Yd3ͅ+WHҎHuafjCk2K ,em}_a=Bw[>J>3l\I=^zLwRҺA3klW ̸-.U>5+\?A٦n]ؑQ1?Q"Ga> 12 Zc"@)͉'N.KcN_R>I=5р a-n"a3(֊8.Jty qJºZX gC