plyr/0000755000176200001440000000000013627466102011247 5ustar liggesusersplyr/NAMESPACE0000644000176200001440000000422713627312250012465 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method("[",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,indexed_array) 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(tryNULL) export(try_default) export(tryapply) export(unrowname) export(vaggregate) importFrom(Rcpp,sourceCpp) importFrom(stats,setNames) useDynLib(plyr) useDynLib(plyr, .registration = TRUE) plyr/LICENSE0000644000176200001440000000005412303221212012230 0ustar liggesusersYEAR: 2014 COPYRIGHT HOLDER: Hadley Wickham plyr/README.md0000644000176200001440000000451513401771117012526 0ustar liggesusers# plyr [![Lifecycle: retired](https://img.shields.io/badge/lifecycle-retired-orange.svg)](https://www.tidyverse.org/lifecycle/#retired) [![CRAN status](https://www.r-pkg.org/badges/version/plyr)](https://cran.r-project.org/package=plyr) [![Travis build status](https://travis-ci.org/hadley/plyr.svg?branch=master)](https://travis-ci.org/hadley/plyr) [![Codecov test coverage](https://codecov.io/gh/hadley/plyr/branch/master/graph/badge.svg)](https://codecov.io/gh/hadley/plyr?branch=master) 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. ## Status [![Lifecycle: retired](https://img.shields.io/badge/lifecycle-retired-orange.svg)](https://www.tidyverse.org/lifecycle/#retired) plyr is retired: this means only changes necessary to keep it on CRAN will be made. We recommend using [dplyr](http://dplyr.tidyverse.org/) (for data frames) or [purrr](http://purrr.tidyverse.org/) (for lists) instead. plyr/data/0000755000176200001440000000000013627315360012157 5ustar liggesusersplyr/data/ozone.rda0000644000176200001440000004466012034020705013776 0ustar liggesusers7zXZi"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.rda0000644000176200001440000104362012034020705014405 0ustar liggesusers7zXZi"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 gC1 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{Warning}{ Passing a data frame as first argument may lead to unexpected results, see \url{https://github.com/hadley/plyr/issues/212}. } \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}()} } \concept{array input} \concept{array output} \keyword{manip} plyr/man/splitter_a.Rd0000644000176200001440000000335213573503245014462 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/splitter-a.r \name{splitter_a} \alias{splitter_a} \title{Split an array by .margins.} \usage{ splitter_a(data, .margins = 1L, .expand = TRUE, .id = NA) } \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.} \item{.id}{names of the split label. Pass \code{NULL} to avoid creation of split labels. Omit or pass \code{NA} to use the default names \code{"X1"}, \code{"X2"}, \ldots. Otherwise, this argument must have the same length as \code{.margins}.} } \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}()} } \concept{splitter functions} \keyword{internal} plyr/man/id.Rd0000644000176200001440000000126613401763754012715 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/id.r \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/raply.Rd0000644000176200001440000000303413401763754013443 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/raply.r \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/list_to_dataframe.Rd0000644000176200001440000000144113573503245015772 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/list-to-dataframe.r \name{list_to_dataframe} \alias{list_to_dataframe} \title{List to data frame.} \usage{ list_to_dataframe(res, labels = NULL, id_name = NULL, id_as_factor = FALSE) } \arguments{ \item{res}{list of input data} \item{labels}{a data frame of labels, one row for each element of res} \item{idname}{the name of the index column, \code{NULL} for no index column} } \description{ Reduce/simplify a list of homogenous objects to a data frame. All \code{NULL} entries are removed. Remaining entries must be all atomic or all data frames. } \seealso{ Other list simplification functions: \code{\link{list_to_array}()}, \code{\link{list_to_vector}()} } \concept{list simplification functions} \keyword{internal} plyr/man/name_rows.Rd0000644000176200001440000000143713401763754014313 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/name-rows.r \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)) } \keyword{manip} plyr/man/summarise.Rd0000644000176200001440000000223013401763754014316 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/summarise.r \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 analogous way to \code{\link{mutate}}, except instead of adding columns to an existing data frame, it creates a new data frame. This is particularly useful in conjunction with \code{\link{ddply}} as it makes it easy to perform group-wise summaries. } \note{ Be careful when using existing variable names; the corresponding columns will be immediately updated with the new data and this can affect subsequent operations referring to those variables. } \examples{ # Let's extract the number of teams and total period of time # 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/indexed_df.Rd0000644000176200001440000000075013401763754014407 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/indexed-data-frame.r \name{indexed_df} \alias{indexed_df} \title{An indexed data frame.} \usage{ indexed_df(data, index, vars) } \arguments{ \item{index}{list of indices} \item{vars}{a character vector giving the variables used for subsetting} \item{env}{environment containing data frame} } \description{ Create a indexed list, a space efficient way of indexing into a large data frame } \keyword{internal} plyr/man/here.Rd0000644000176200001440000000152413401763754013241 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/here.r \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/is.formula.Rd0000644000176200001440000000043213401763754014372 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.r \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/ddply.Rd0000644000176200001440000000724213573503245013432 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ddply.r \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{.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{.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{.inform}{produce informative error messages? This is turned off by default because it substantially slows processing speed, but is very useful for debugging} \item{.drop}{should combinations of variables that do not appear in the input data be preserved (FALSE) or dropped (TRUE, default)} \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.} } \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. To apply a function for each row, use \code{\link{adply}} with \code{.margins} set to \code{1}. } \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 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}()} } \concept{data frame input} \concept{data frame output} \keyword{manip} plyr/man/splitter_d.Rd0000644000176200001440000000314113573503245014461 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/splitter-d.r \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}()} } \concept{splitter functions} \keyword{internal} plyr/man/vaggregate.Rd0000644000176200001440000000320513573503245014425 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/vaggregate.r \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.out = 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/id_var.Rd0000644000176200001440000000035713401763754013565 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/id.r \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/as.quoted.Rd0000644000176200001440000000153013401763754014216 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quote.r \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[=quoted]{.}} } plyr/man/unrowname.Rd0000644000176200001440000000041013401763754014322 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.r \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/eval.quoted.Rd0000644000176200001440000000072213401763754014544 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quote.r \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{try}{if TRUE, return \code{NULL} if evaluation unsuccesful} \item{expr}{quoted object to evalution} } \value{ a list } \description{ Evaluates quoted variables in specified environment } \keyword{internal} plyr/man/mlply.Rd0000644000176200001440000000522513573503245013452 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/mlply.r \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{.data}{matrix or data frame to use as source of arguments} \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \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{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.inform}{produce informative error messages? This is turned off by default because it substantially slows processing speed, but is very useful for debugging} \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.} } \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 multiple arguments input: \code{\link{m_ply}()}, \code{\link{maply}()}, \code{\link{mdply}()} Other list output: \code{\link{alply}()}, \code{\link{dlply}()}, \code{\link{llply}()} } \concept{list output} \concept{multiple arguments input} \keyword{manip} plyr/man/desc.Rd0000644000176200001440000000066513401763754013241 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/arrange.r \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/join.Rd0000644000176200001440000000360013401763754013252 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/join.r \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/arrange.Rd0000644000176200001440000000216213401763754013734 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/arrange.r \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/compact.Rd0000644000176200001440000000042413401763754013742 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.r \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/match_df.Rd0000644000176200001440000000316513401763754014066 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/match-df.r \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/failwith.Rd0000644000176200001440000000115613401763754014126 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/try.r \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/tryapply.Rd0000644000176200001440000000066413401763754014206 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/try.r \name{tryapply} \alias{tryapply} \title{Apply with built in try. Uses compact, lapply and tryNULL} \usage{ tryapply(list, fun, ...) } \arguments{ \item{list}{list to apply function \code{f} on} \item{...}{further arguments to \code{f}} \item{f}{function} } \description{ Apply with built in try. Uses compact, lapply and tryNULL } \keyword{internal} plyr/man/quoted.Rd0000644000176200001440000000340113401763754013613 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quote.r \name{.} \alias{.} \alias{quoted} \alias{is.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/isplit2.Rd0000644000176200001440000000062113401763754013701 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/liply.r \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. } \section{Warning}{ Deprecated, do not use in new code. } \seealso{ \code{\link{plyr-deprecated}} } \keyword{internal} plyr/man/rename.Rd0000644000176200001440000000171613401763754013570 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rename.r \name{rename} \alias{rename} \title{Modify names by name, not position.} \usage{ rename(x, replace, warn_missing = TRUE, warn_duplicated = 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}.} \item{warn_duplicated}{print a message if any name appears more than once in \code{x} after the operation. 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/revalue.Rd0000644000176200001440000000216113401763754013757 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/revalue.r \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/mutate.Rd0000644000176200001440000000233113401763754013612 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/mutate.r \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/r_ply.Rd0000644000176200001440000000174313401763754013446 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/r_ply.r \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/progress_text.Rd0000644000176200001440000000161413573503245015223 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/progress.r \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}()} } \concept{progress bars} plyr/man/progress_win.Rd0000644000176200001440000000155513573503245015040 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/progress.r \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}()} } \concept{progress bars} plyr/man/split_labels.Rd0000644000176200001440000000075613401763754015001 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/splitter-d.r \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/llply.Rd0000644000176200001440000000432213573503245013446 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/llply.r \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{.data}{list to be processed} \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{.inform}{produce informative error messages? This is turned off by default because it substantially slows processing speed, but is very useful for debugging} \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.} } \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}()} } \concept{list input} \concept{list output} \keyword{manip} plyr/man/plyr-deprecated.Rd0000644000176200001440000000064613401763754015406 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/plyr-deprecated.r \name{plyr-deprecated} \alias{plyr-deprecated} \title{Deprecated Functions in Package plyr} \description{ These functions are provided for compatibility with older versions of \code{plyr} only, and may be defunct as soon as the next release. } \details{ \itemize{ \item \code{\link{liply}} \item \code{\link{isplit2}} } } plyr/man/is.discrete.Rd0000644000176200001440000000064213401763754014532 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.r \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/mapvalues.Rd0000644000176200001440000000255013401763754014313 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/revalue.r \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/names.quoted.Rd0000644000176200001440000000067513401763754014727 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quote.r \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/list_to_array.Rd0000644000176200001440000000122613573503245015165 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/list-to-array.r \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}()} } \concept{list simplification functions} \keyword{internal} plyr/man/plyr.Rd0000644000176200001440000000512613573503245013303 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/plyr.r \docType{package} \name{plyr} \alias{plyr} \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/split_indices.Rd0000644000176200001440000000125413401763754015147 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/RcppExports.R \name{split_indices} \alias{split_indices} \title{Split indices.} \usage{ split_indices(group, n = 0L) } \arguments{ \item{n}{largest integer (may not appear in index). This is hint: if the largest value of \code{group} is bigger than \code{n}, the output will silently expand.} \item{index}{integer indices} } \description{ An optimised version of split for the special case of splitting row indices into groups, as used by \code{\link{splitter_d}}. } \examples{ split_indices(sample(10, 100, rep = TRUE)) split_indices(sample(10, 100, rep = TRUE), 10) } \keyword{internal} \keyword{manip} plyr/man/dlply.Rd0000644000176200001440000000524713573503245013445 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dlply.r \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{.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{.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{.inform}{produce informative error messages? This is turned off by default because it substantially slows processing speed, but is very useful for debugging} \item{.drop}{should combinations of variables that do not appear in the input data be preserved (FALSE) or dropped (TRUE, default)} \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.} } \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. To apply a function for each row, use \code{\link{alply}} with \code{.margins} set to \code{1}. } \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}()} } \concept{data frame input} \concept{list output} \keyword{manip} plyr/man/ldply.Rd0000644000176200001440000000510513573503245013436 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ldply.r \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, .id = NA ) } \arguments{ \item{.data}{list to be processed} \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{.inform}{produce informative error messages? This is turned off by default because it substantially slows processing speed, but is very useful for debugging} \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{.id}{name of the index column (used if \code{.data} is a named list). Pass \code{NULL} to avoid creation of the index column. For compatibility, omit this argument or pass \code{NA} to avoid converting the index column to a factor; in this case, \code{".id"} is used as colum name.} } \value{ A data frame, as described in the output section. } \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 list input: \code{\link{l_ply}()}, \code{\link{laply}()}, \code{\link{llply}()} Other data frame output: \code{\link{adply}()}, \code{\link{ddply}()}, \code{\link{mdply}()} } \concept{data frame output} \concept{list input} \keyword{manip} plyr/man/baseball.Rd0000644000176200001440000000347213401763754014067 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/data.r \docType{data} \name{baseball} \alias{baseball} \title{Yearly batting records for all major league baseball players} \format{A 21699 x 22 data frame} \usage{ baseball } \description{ This data frame contains batting statistics for a subset of players collected from \url{http://www.baseball-databank.org/}. There are a total of 21,699 records, covering 1,228 players from 1871 to 2007. Only players with more 15 seasons of play are included. } \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/rlply.Rd0000644000176200001440000000217213401763754013460 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rlply.r \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/reduce_dim.Rd0000644000176200001440000000042113401763754014411 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dimensions.r \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/print.split.Rd0000644000176200001440000000051713401763754014605 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/split.r \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/l_ply.Rd0000644000176200001440000000413113573503245013427 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/l_ply.r \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{.data}{list to be processed} \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{.inform}{produce informative error messages? This is turned off by default because it substantially slows processing speed, but is very useful for debugging} \item{.print}{automatically print each result? (default: \code{FALSE})} \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.} } \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. } \examples{ l_ply(llply(mtcars, round), table, .print = TRUE) l_ply(baseball, function(x) print(summary(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 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}()} } \concept{list input} \concept{no output} \keyword{manip} plyr/man/daply.Rd0000644000176200001440000000567713573503245013441 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/daply.r \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{.data}{data frame to be processed} \item{.variables}{variables to split data frame by, as quoted variables, a formula or character vector} \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{.inform}{produce informative error messages? This is turned off by default because it substantially slows processing speed, but is very useful for debugging} \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}} \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.} } \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}}. To apply a function for each row, use \code{\link{aaply}} with \code{.margins} set to \code{1}. } \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}()} } \concept{array output} \concept{data frame input} \keyword{manip} plyr/man/loop_apply.Rd0000644000176200001440000000073413401763754014476 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/loop_apply.R \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/colwise.Rd0000644000176200001440000000376713401763754013776 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/colwise.r \name{colwise} \alias{colwise} \alias{catcolwise} \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/amv_dimnames.Rd0000644000176200001440000000101213401763754014746 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dimensions.r \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/quickdf.Rd0000644000176200001440000000065113401763754013744 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quickdf.r \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_tk.Rd0000644000176200001440000000174713573503245014664 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/progress.r \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}()} } \concept{progress bars} plyr/man/strip_splits.Rd0000644000176200001440000000116013401763754015051 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/strip-splits.r \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/join_all.Rd0000644000176200001440000000172013401763754014103 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/join-all.r \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/true.Rd0000644000176200001440000000054613401763754013300 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.r \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/try_default.Rd0000644000176200001440000000120513401763754014634 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/try.r \name{try_default} \alias{try_default} \alias{tryNULL} \title{Try, with default in case of error.} \usage{ try_default(expr, default, quiet = FALSE) tryNULL(expr) } \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. \code{tryNULL} provides a useful special case when dealing with lists. } \seealso{ \code{\link{tryapply}} } \keyword{internal} plyr/man/amv_dim.Rd0000644000176200001440000000045613401763754013735 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dimensions.r \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/print.quoted.Rd0000644000176200001440000000044313401763754014751 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quote.r \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/round_any.Rd0000644000176200001440000000153013401763754014311 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/round-any.r \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/get-split.Rd0000644000176200001440000000052213401763754014223 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/split.r \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/liply.Rd0000644000176200001440000000142113401763754013443 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/liply.r \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. } \section{Warning}{ Deprecated, do not use in new code. } \seealso{ \code{\link{plyr-deprecated}} } \keyword{manip} plyr/man/rbind.fill.matrix.Rd0000644000176200001440000000305513573503245015642 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rbind-fill-matrix.r \name{rbind.fill.matrix} \alias{rbind.fill.matrix} \title{Bind matrices by row, and fill missing columns with NA.} \usage{ \method{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) } \seealso{ \code{\link[base]{rbind}}, \code{\link[base]{cbind}}, \code{\link[plyr]{rbind.fill}} Other binding functions: \code{\link{rbind.fill}()} } \author{ C. Beleites } \concept{binding functions} \keyword{manip} plyr/man/rbind.fill.Rd0000644000176200001440000000257613573503245014346 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rbind-fill.r \name{rbind.fill} \alias{rbind.fill} \title{Combine data.frames by row, filling in missing columns.} \usage{ \method{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. Any NULL inputs are silently dropped. If all inputs are NULL, the output is NULL.} } \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. Unordered factor columns will have their levels unified and character data bound with factors will be converted to character. POSIXct data will be converted to be in the same time zone. Array and matrix columns must have identical dimensions after the row count. Aside from these there are no general checks that each column is of consistent data type. } \examples{ rbind.fill(mtcars[c("mpg", "wt")], mtcars[c("wt", "cyl")]) } \seealso{ Other binding functions: \code{\link{rbind.fill.matrix}()} } \concept{binding functions} \keyword{manip} plyr/man/adply.Rd0000644000176200001440000000573313573503245013432 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/adply.r \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, .id = NA ) } \arguments{ \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{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \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{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.inform}{produce informative error messages? This is turned off by default because it substantially slows processing speed, but is very useful for debugging} \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{.id}{name(s) of the index column(s). Pass \code{NULL} to avoid creation of the index column(s). Omit or pass \code{NA} to use the default names \code{"X1"}, \code{"X2"}, \ldots. Otherwise, this argument must have the same length as \code{.margins}.} } \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}()} } \concept{array input} \concept{data frame output} \keyword{manip} plyr/man/alply.Rd0000644000176200001440000000543413573503245013440 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/alply.r \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{.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{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \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{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.inform}{produce informative error messages? This is turned off by default because it substantially slows processing speed, but is very useful for debugging} \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{.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}()} } \concept{array input} \concept{list output} \keyword{manip} plyr/man/idata.frame.Rd0000644000176200001440000000143613401763754014473 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/idataframe.r \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/progress_time.Rd0000644000176200001440000000112713573503245015174 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/progress-time.r \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}()} } \concept{progress bars} plyr/man/d_ply.Rd0000644000176200001440000000461513573503245013426 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/d_ply.r \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{.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{.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{.inform}{produce informative error messages? This is turned off by default because it substantially slows processing speed, but is very useful for debugging} \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})} \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.} } \value{ Nothing } \description{ For each subset of a data frame, apply function and discard results. To apply a function for each row, use \code{\link{a_ply}} with \code{.margins} set to \code{1}. } \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}()} } \concept{data frame input} \concept{no output} \keyword{manip} plyr/man/dims.Rd0000644000176200001440000000042013401763754013244 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dimensions.r \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/as.list.split.Rd0000644000176200001440000000061213401763754015022 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/split.r \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/maply.Rd0000644000176200001440000000561013573503245013435 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/maply.r \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{.data}{matrix or data frame to use as source of arguments} \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \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{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.inform}{produce informative error messages? This is turned off by default because it substantially slows processing speed, but is very useful for debugging} \item{.drop}{should extra dimensions of length 1 in the output be dropped, simplifying the output. Defaults to \code{TRUE}} \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.} } \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 multiple arguments input: \code{\link{m_ply}()}, \code{\link{mdply}()}, \code{\link{mlply}()} Other array output: \code{\link{aaply}()}, \code{\link{daply}()}, \code{\link{laply}()} } \concept{array output} \concept{multiple arguments input} \keyword{manip} plyr/man/m_ply.Rd0000644000176200001440000000514613573503245013437 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/m_ply.r \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{.data}{matrix or data frame to use as source of arguments} \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \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{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.inform}{produce informative error messages? This is turned off by default because it substantially slows processing speed, but is very useful for debugging} \item{.print}{automatically print each result? (default: \code{FALSE})} \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.} } \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}()} } \concept{multiple arguments input} \concept{no output} \keyword{manip} plyr/man/empty.Rd0000644000176200001440000000045413401763754013455 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.r \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/nunique.Rd0000644000176200001440000000047113401763754014002 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.r \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/each.Rd0000644000176200001440000000173013401763754013215 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/each.r \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/join.keys.Rd0000644000176200001440000000067413401763754014234 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/join.r \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/indexed_array.Rd0000644000176200001440000000074513401763754015140 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/indexed-array.r \name{indexed_array} \alias{indexed_array} \alias{[[.indexed_array} \alias{names.indexed_array} \alias{length.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/a_ply.Rd0000644000176200001440000000464213573503245013423 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/a_ply.r \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{.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{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \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{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.inform}{produce informative error messages? This is turned off by default because it substantially slows processing speed, but is very useful for debugging} \item{.print}{automatically print each result? (default: \code{FALSE})} \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.} } \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}()} } \concept{array input} \concept{no output} \keyword{manip} plyr/man/create_progress_bar.Rd0000644000176200001440000000350413401763754016331 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/progress.r \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/mdply.Rd0000644000176200001440000000614313573503245013442 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/mdply.r \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{.data}{matrix or data frame to use as source of arguments} \item{.fun}{function to apply to each piece} \item{...}{other arguments passed on to \code{.fun}} \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{.progress}{name of the progress bar to use, see \code{\link{create_progress_bar}}} \item{.inform}{produce informative error messages? This is turned off by default because it substantially slows processing speed, but is very useful for debugging} \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.} } \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 multiple arguments input: \code{\link{m_ply}()}, \code{\link{maply}()}, \code{\link{mlply}()} Other data frame output: \code{\link{adply}()}, \code{\link{ddply}()}, \code{\link{ldply}()} } \concept{data frame output} \concept{multiple arguments input} \keyword{manip} plyr/man/rdply.Rd0000644000176200001440000000252013401763754013445 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rdply.r \name{rdply} \alias{rdply} \title{Replicate expression and return results in a data frame.} \usage{ rdply(.n, .expr, .progress = "none", .id = NA) } \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{.id}{name of the index column. Pass \code{NULL} to avoid creation of the index column. For compatibility, omit this argument or pass \code{NA} to use \code{".n"} as column name.} } \value{ a data frame } \description{ Evaluate 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/list_to_vector.Rd0000644000176200001440000000074613573503245015357 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/list-to-vector.r \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}()} } \concept{list simplification functions} \keyword{internal} plyr/man/ozone.Rd0000644000176200001440000000236413401763754013453 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/data.r \docType{data} \name{ozone} \alias{ozone} \title{Monthly ozone measurements over Central America.} \format{A 24 x 24 x 72 numeric array} \usage{ ozone } \description{ This data set is a subset of the data from the 2006 ASA Data expo challenge, \url{http://stat-computing.org/dataexpo/2006/}. The data are monthly ozone averages on a very coarse 24 by 24 grid covering Central America, from Jan 1995 to Dec 2000. The data is stored in a 3d area with the first two dimensions representing latitude and longitude, and the third representing time. } \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/take.Rd0000644000176200001440000000133113401763754013236 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/take.r \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) } \keyword{manip} plyr/man/progress_none.Rd0000644000176200001440000000113313573503245015172 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/progress.r \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}()} } \concept{progress bars} \keyword{internal} plyr/DESCRIPTION0000644000176200001440000000236013627466102012756 0ustar liggesusersPackage: plyr Title: Tools for Splitting, Applying and Combining Data Version: 1.8.6 Authors@R: person(given = "Hadley", family = "Wickham", role = c("aut", "cre"), email = "hadley@rstudio.com") Description: 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 piece 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 'Becton Dickinson'. License: MIT + file LICENSE URL: http://had.co.nz/plyr, https://github.com/hadley/plyr BugReports: https://github.com/hadley/plyr/issues Depends: R (>= 3.1.0) Imports: Rcpp (>= 0.11.0) Suggests: abind, covr, doParallel, foreach, iterators, itertools, tcltk, testthat LinkingTo: Rcpp Encoding: UTF-8 LazyData: true RoxygenNote: 7.0.2 NeedsCompilation: yes Packaged: 2020-03-02 23:46:56 UTC; hadley Author: Hadley Wickham [aut, cre] Maintainer: Hadley Wickham Repository: CRAN Date/Publication: 2020-03-03 14:40:02 UTC plyr/tests/0000755000176200001440000000000012506322602012400 5ustar liggesusersplyr/tests/testthat/0000755000176200001440000000000013627466102014251 5ustar liggesusersplyr/tests/testthat/test-inform.r0000644000176200001440000000345012512025772016701 0ustar liggesuserscontext("Informative messages") test_that(".inform parameter works for all l?ply functions", { funcnames <- ls(name = asNamespace("plyr"), pattern = "^l[^i]ply$") old_options <- options(show.error.messages = FALSE) on.exit(options(old_options), add = TRUE) input <- 1:10 for (funcname in funcnames) { func <- get(funcname, asNamespace("plyr")) expect_error(func(input, function(...) stop("qq"), .inform = TRUE), "piece 1", info = funcname) } }) test_that(".inform parameter works for all d?ply functions", { funcnames <- ls(name = asNamespace("plyr"), pattern = "^d[^i]ply$") old_options <- options(show.error.messages = FALSE) on.exit(options(old_options), add = TRUE) input <- data.frame(a = 1:10) for (funcname in funcnames) { func <- get(funcname, asNamespace("plyr")) expect_error(func(input, .(), function(...) stop("qq"), .inform = TRUE), "piece 1", info = funcname) } }) test_that(".inform parameter works for all a?ply functions", { funcnames <- ls(name = asNamespace("plyr"), pattern = "^a[^i]ply$") old_options <- options(show.error.messages = FALSE) on.exit(options(old_options), add = TRUE) input <- data.frame(a = 1:10) for (funcname in funcnames) { func <- get(funcname, asNamespace("plyr")) expect_error(func(input, 1, function(...) stop("qq"), .inform = TRUE), "piece 1", info = funcname) } }) test_that(".inform parameter works for all m?ply functions", { funcnames <- ls(name = asNamespace("plyr"), pattern = "^m[^i]ply$") old_options <- options(show.error.messages = FALSE) on.exit(options(old_options), add = TRUE) input <- data.frame(a = 1:10) for (funcname in funcnames) { func <- get(funcname, asNamespace("plyr")) expect_error(func(input, function(...) stop("qq"), .inform = TRUE), "piece 1", info = funcname) } }) plyr/tests/testthat/test-rbind.r0000644000176200001440000002213513627304733016513 0ustar liggesuserscontext("rbind.fill") test_that("variable classes are preserved", { a <- data.frame( a = factor(letters[1:3]), b = 1:3, c = date(), stringsAsFactors = TRUE ) 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_s3_class(ab1$a, "factor") expect_type(ab1$b, "integer") expect_s3_class(ab1$c, "factor") expect_s3_class(ab1$d, "Date") expect_s3_class(ab1$e, "POSIXct") expect_equal(dim(ab1$f), c(6, 2)) }) 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("character or factor or list-matrices are preserved", { d1 <- data.frame(a=1:2, x=I(matrix(c('a', 'b', 'c', 'd'), nrow=2))) d2 <- data.frame(b=1:2, x=I(`dim<-`(factor(c('a', 'b', 'c', 'd')), c(2,2)))) d3 <- data.frame(b=1:2, x=I(array(as.list(1:4), c(2,2)))) b1 <- rbind.fill(d1, d1) b2 <- rbind.fill(d2, d2) b3 <- rbind.fill(d3, d3) expect_equal(dim(b1$x), c(4,2)) expect_equal(typeof(b1$x), "character") expect_equal(dim(b2$x), c(4,2)) expect_is(b2$x, "factor") expect_equal(dim(b3$x), c(4,2)) expect_equal(typeof(b3$x), "list") }) test_that("missing levels in factors preserved", { f <- addNA(factor(c("a", "b", NA))) df1 <- data.frame(a = f, c = f) df2 <- data.frame(b = f, c = f) out <- rbind.fill(df1, df2) expect_equal(levels(out$a), levels(f)) expect_equal(levels(out$b), levels(f)) expect_equal(levels(out$c), levels(f)) }) 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("1d arrays treated as vectors", { df <- data.frame(x = 1) df$x <- array(1, 1) #1d arrays converted into vectors df2 <- rbind.fill(df, df) expect_that(df2$x, is_equivalent_to(rbind(df, df)$x)) expect_that(dim(df2$x), equals(dim(rbind(df, df)$x))) #if dims are stripped, dimnames should be also df <- data.frame(x = 1) df$x <- array(2, 1, list(x="one")) df2 <- rbind.fill(df, df) expect_null(dimnames(df2$x)) #can bind 1d array to vector dfV <- data.frame(x=3) dfO1 <- rbind.fill(df, dfV) dfO2 <- rbind.fill(dfV, df) expect_equal(dfO1, data.frame(x=c(2, 3))) expect_equal(dfO2, data.frame(x=c(3, 2))) }) test_that("multidim arrays ok", { library(abind) df <- data.frame(x = 1:3) df$x <- array(1:27, c(3,3,3)) df2 <- rbind.fill(df, df) expect_equal(dim(df2$x), dim(abind(along=1, df$x, df$x))) expect_that(df2$x, is_equivalent_to(abind(along=1, df$x, df$x))) }) test_that("Array column names preserved", { x <- data.frame(hair.color = dimnames(HairEyeColor)[[1]]) x$obs <- unclass(HairEyeColor[,,1]) xx1 <- rbind(x, x) xx2 <- rbind.fill(x, x) #plyr is against row names, but should respect col names like rbind rownames(xx1) <- NULL rownames(xx1$obs) <- NULL #but unlike rbind it should also preserve names-of-dimnames. names(dimnames(xx1$obs)) <- c("", "Eye") expect_equal(xx1, xx2) }) test_that("attributes are preserved", { 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 and convert factors", { d1a <- data.frame(x=c('a','b'), y=1:2) d2a <- data.frame(x=c('c','d'), z=1:2, stringsAsFactors=F) d1b <- data.frame(x=c('a','b'), y=1:2, stringsAsFactors=F) d2b <- data.frame(x=c('c','d'), z=1:2) d3a <- rbind.fill(d1a,d2a) d3b <- rbind.fill(d1b,d2b) expect_equal(d3a$x, c("a", "b", "c", "d")) expect_equal(d3b$x, c("a", "b", "c", "d")) }) test_that("factor to character conversion preserves attributes", { d1 <- data.frame(a = letters[1:10], b = factor(letters[11:20]), stringsAsFactors=FALSE) d2 <- data.frame(a = factor(letters[11:20]), b = letters[11:20], stringsAsFactors=FALSE) attr(d1$a, "foo") <- "one" attr(d1$b, "foo") <- "two" attr(d2$a, "foo") <- "bar" attr(d2$b, "foo") <- "baz" d12 <- rbind.fill(d1, d2) expect_equal(attr(d12$a, "foo"), "one") expect_equal(attr(d12$b, "foo"), "two") }) test_that("zero row data frames ok", { 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) }) test_that("rbind.fill rejects non-vector columns", { a <- list(a=list(1), b=c(3), c="d", f=function() NULL) attr(a, "row.names") <- c(NA_integer_, -1) class(a) <- "data.frame" expect_error(rbind.fill(a,a), "cannot make") }) test_that("rbind.fill rejects data frame columns", { a <- data.frame(a=1:3, b=2:4, c=3:5) a$c <- data.frame(x=10:12, y=11:13) rownames(a) <- NULL rownames(a$c) <- NULL expect_error(rbind.fill(a,a), "not supported") }) rbind_time <- function(size, classes = c("numeric", "character", "array", "factor", "time")) { unit <- quickdf(list(numeric = 1:3, character = c("a", "b", "c"), array = array(1:6, c(3,2)), factor = factor(c("a", "b", "c")), time = as.POSIXct(Sys.time()) + 1:3)) args <- rep(list(unit[classes]), size) system.time(do.call(rbind.fill, args)) } get_rbind_times <- function(...) { # nolint start rbind_time(10) #warm up/JIT mdply(.fun = rbind_time, ...) # nolint end } if (identical(Sys.getenv("NOT_CRAN"), "true") && !identical(Sys.getenv("TRAVIS"), "true")) { expect_linear_enough <- function(timings, threshold=0.1) { #expect that no more than `threshold` of a `size` input's runtime is #accounted for by quadratic behavior model <- lm(I(user.self / size) ~ size, timings) expect_lt(threshold, summary(model)$coefficients[2,4]) } test_that("rbind.fill performance linear", { timings <- get_rbind_times(data.frame(size = 2 ^ (1:10)), classes=c("numeric", "character", "array")) expect_linear_enough(timings) }) test_that("rbind.fill performance linear with factors", { timings <- get_rbind_times(data.frame(size = 2 ^ (1:10)), classes=c("factor")) expect_linear_enough(timings) }) test_that("rbind.fill performance linear with times", { timings <- get_rbind_times(data.frame(size = 2 ^ (1:10)), classes=c("time")) expect_linear_enough(timings) }) test_that("NULLs silently dropped", { expect_equal(rbind.fill(mtcars, NULL), mtcars) expect_equal(rbind.fill(NULL, mtcars), mtcars) expect_equal(rbind.fill(NULL, NULL), NULL) }) } plyr/tests/testthat/test-rename.r0000644000176200001440000001075312513035176016662 0ustar liggesusers# Main-stream cases ----------------------------------- context("Rename - Expected Usage") 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)) }) # Duplicate Names ----------------------------------- context("Rename - Duplicates") # This batch tests the typical renaming scenarios test_that("Renaming list with one conflicting variable name - default", { x <- list(a = 1, b = 2, c = 3) replace_list <- c("c" = "f", "b" = "e", "a" = "f") expected_response <- "created duplicates" #The exact match would be: "The plyr::rename operation has created duplicates for the following name\\(s\\): \\(`f`\\)" expect_warning(rename(x = x, replace = replace_list), expected_response) }) test_that("Renaming list with two conflicting variable names - default", { x <- list(a = 1, b = 2, c = 3, d = 4, e = 5) replace_list <- c("c" = "f", "b" = "e", "a" = "f", "d" = "g", "e" = "g") expected_response <- "created duplicates" #The exact match would be: "The plyr::rename operation has created duplicates for the following name\\(s\\): \\(`f`, `g`\\)" expect_warning(rename(x = x, replace = replace_list), expected_response) }) test_that("Renaming list with two conflicting variable names - default", { x <- list(a = 1, b = 2, c = 3, d = 4, e = 5) replace_list <- c("c" = "f", "b" = "e", "a" = "f", "d" = "g", "e" = "g") expected_response <- "created duplicates" #The exact match would be: "The plyr::rename operation has created duplicates for the following name\\(s\\): \\(`f`, `g`\\)" expect_warning(rename(x = x, replace = replace_list), expected_response) }) test_that("Renaming list with an conflicting variable name - without warning", { x <- list(a = 1, b = 2, c = 3) replace_list <- c("c" = "f", "b" = "e", "a" = "f") result <- rename(x = x, replace = replace_list, warn_duplicated = FALSE) expect_identical(result, list(f = 1, e = 2, f = 3)) }) # This batch tests the boundary cases test_that("Renaming to the same value", { #One element is renamed to itself x <- list(a = 1, b = 2, c = 3) replace_list <- c("a" = "a") expected_value <- x expect_identical(rename(x = x, replace = replace_list), expected_value) }) test_that("Renaming list with an empty renaming vector", { #No renames are requested (which could happen if the calling code was under a lot of automated code.) x <- list(a = 1, b = 2, c = 3) replace_list <- c() expected_value <- x expect_identical(rename(x = x, replace = replace_list), expected_value) }) test_that("Single Swapping (shouldn't cause problems)", { #Notice how a becomes c, while c becomes f. x <- list(a = 1, b = 2, c = 3) replace_list <- c("c" = "f", "b" = "e", "a" = "c") expected_value <- list(c = 1, e = 2, f = 3) actual_value <- rename(x = x, replace = replace_list) expect_identical(actual_value, expected_value) }) test_that("Double Swapping (shouldn't cause problems)", { #Notice how a becomes c, while c becomes a. x <- list(a = 1, b = 2, c = 3) replace_list <- c("c" = "a", "b" = "z", "a" = "c") expected_value <- list(c = 1, z = 2, a = 3) actual_value <- rename(x = x, replace = replace_list) expect_identical(actual_value, expected_value) }) test_that("Multiple assignments for the same element", { #Notice how it requests to change a to d, e, and f. x <- list(a = 1, b = 2, c = 3) replace_list <- c("a" = "d", "a" = "e", "a" = "f") expected_response <- "The following `from` values were not present in `x`: a, a" expected_value <- list(a = 1, a = 2, a = 3) expect_message(rename(x = x, replace = replace_list), expected_response) }) plyr/tests/testthat/test-mapply.r0000644000176200001440000000160312034020705016675 0ustar liggesuserscontext("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/tests/testthat/test-empty.r0000644000176200001440000000245512043514644016551 0ustar liggesuserscontext("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/tests/testthat/test-debug.r0000644000176200001440000000076312512025470016474 0ustar liggesuserscontext("Debugging") test_that("failwith() function", { expect_equal(failwith(1:10, stop, quiet = TRUE)("error"), 1:10) }) test_that("tryNULL() function", { old_options <- options(show.error.messages = FALSE) on.exit(options(old_options), add = TRUE) expect_equal(tryNULL(stop("error")), NULL) }) test_that("tryapply() function", { safe_divide <- function(y, x) { stopifnot(y != 0) x / y } expect_equal(tryapply(-3:3, safe_divide, x = 1), as.list(1 / (-3:3)[-4])) }) plyr/tests/testthat/test-quote.r0000644000176200001440000000352712512025470016544 0ustar liggesuserscontext("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("can't pass bogus environment for evaluation", { expect_that(eval.quoted(.(x), envir = -1), throws_error("must be")) }) 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("failsafe evaluation", { b <- 2 x <- local({ a <- 1 .(a) }) expect_that(eval.quoted(x, try = TRUE)$b, equals(NULL)) }) test_that("names work for long expressions", { # nolint start q <- .(foo = barjasdfgjadhfgjsdhfgusdhfgusheguisdhguioahsrofasdgsdfgsdfg + dfgafgasdfgsdfgsdfgsdfgsdfgsdfgsdfg) # nolint end expect_that(names(q), equals("foo")) }) test_that("printing works", { expect_that(print(as.quoted(NULL)), testthat::prints_text("list()")) expect_that(print(as.quoted("id")), testthat::prints_text("id")) expect_that(print(as.quoted("3")), testthat::prints_text("3")) expect_that(print(as.quoted(c("a", "b"))), testthat::prints_text("List of 2")) expect_that(print(as.quoted(~a+b)), testthat::prints_text("List of 2")) expect_that(print(as.quoted(~a)), testthat::prints_text("List of 1")) expect_that(print(as.quoted(as.name("a"))), testthat::prints_text("List of 1")) }) test_that("concatenation", { expect_equal(c(.(a), .(b)), .(a, b)) expect_equal(c(.(a), .(b, c)), .(a, b, c)) expect_equal(c(.(a), .(b), .(c)), .(a, b, c)) }) test_that("extraction", { expect_equal(.(a, b)[1], .(a)) expect_equal(.(a, b, c)[-1], .(b, c)) }) plyr/tests/testthat/test-mutate.r0000644000176200001440000000137312512025470016703 0ustar liggesuserscontext("Mutate") test_that("mutate behaves the same as transform", { m1 <- mutate(airquality, Ozone = -Ozone) t1 <- transform(airquality, Ozone = -Ozone) expect_that(m1, equals(t1)) m2 <- mutate(airquality, new = -Ozone, Temp = (Temp - 32) / 1.8) t2 <- transform(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)) }) test_that("mutating a column twice does not work", { # For compatibility, see #218 m1 <- mutate(airquality, dm = 0, dm = Month + Day / 31) expect_equal(m1$dm, rep(0, length(m1$dm))) }) plyr/tests/testthat/test-join.r0000644000176200001440000001515012512025470016341 0ustar liggesuserscontext("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")) }) test_that("strings match to factors", { dfF <- data.frame(character = c("Aeryn", "Jothee", "Jothee", "Chiana", "Scorpius", "Scorpius"), species = c("Sebacian", "Luxan", "Sebacian", "Nibari", "Sebacian", "Scarran"), stringsAsFactors = TRUE) dfS <- colwise(as.character)(dfF) matchF <- data.frame(species = "Sebacian", stringsAsFactors = TRUE) matchS <- colwise(as.character)(matchF) #nor does `join`, (so inner joins are not commutative) expect_equal(3, nrow(join(dfF, matchF, type = "inner", by="species"))) expect_equal(3, nrow(join(dfS, matchS, type = "inner", by="species"))) expect_equal(3, nrow(join(dfS, matchF, type = "inner", by="species"))) expect_equal(3, nrow(join(dfF, matchS, type = "inner", by="species"))) }) test_that("join_all", { df <- expand.grid(.id = 1, a = 1:2, b = 4:5, c = letters[1:2], d = letters[4:5], KEEP.OUT.ATTRS = FALSE, stringsAsFactors = FALSE) df$.id <- as.integer(rownames(df)) expect_equal(join_all(list(df)), df) expect_equal(join_all(list(df[, c(1,2)], df[, c(1,3,4,5)])), df) expect_equal(join_all(list(df[, c(1,2)], df[, c(1,3,4)], df[, c(1,4,5)])), df) }) test_that("match_df", { df <- expand.grid(.id = 1, a = 1:2, b = 4:5, c = letters[1:2], d = letters[4:5], KEEP.OUT.ATTRS = FALSE, stringsAsFactors = FALSE) expect_equal(match_df(df, df), df) expect_equal(match_df(df, df), df) expect_equal(nrow(match_df(df, data.frame(a=1, b=4))), 4) }) plyr/tests/testthat/test-split-labels.r0000644000176200001440000000041213627304755020006 0ustar liggesuserscontext("Split labels") test_that("Empty levels preserved", { df <- data.frame( fac1 = letters[1:4], fac2 = LETTERS[1:4], stringsAsFactors = TRUE ) a <- split_labels(df, FALSE) b <- split_labels(df[1, ], FALSE) expect_that(a, equals(b)) }) plyr/tests/testthat/test-id.r0000644000176200001440000000751512512025470016004 0ustar liggesuserscontext("ID column name") test_that(".id parameter for ldply", { data <- setNames(nm = 1:10) expect_equal(names(ldply(data, identity)), c(".id", "V1")) expect_equal(names(ldply(data, identity, .id = NULL)), c("V1")) expect_equal(names(ldply(data, identity, .id = NA)), c(".id", "V1")) expect_equal(names(ldply(data, identity, .id = "ID")), c("ID", "V1")) }) test_that("ID column is a factor if .id argument is set", { data <- setNames(nm = 1:10) expect_false(is.factor(ldply(data, identity)$.id)) expect_true(is.factor(ldply(data, identity, .id = "ID")$ID)) }) test_that(".id parameter for rdply", { expect_equal(names(rdply(10, 0)), c(".n", "V1")) expect_false(is.factor(rdply(10, 0)$.n)) expect_equal(names(rdply(10, 0, .id = NULL)), c("V1")) expect_equal(names(rdply(10, 0, .id = NA)), c(".n", "V1")) expect_equal(names(rdply(10, 0, .id = "ID")), c("ID", "V1")) expect_false(is.factor(rdply(10, 0, .id = "ID")$ID)) }) test_that(".id parameter for adply", { data <- array(1:27, dim = c(3, 3, 3)) expect_equal(names(adply(data, 1, identity)), c("X1", "1", "2", "3")) expect_equal(names(adply(data, 2, identity)), c("X1", "1", "2", "3")) expect_equal(names(adply(data, 3, identity)), c("X1", "1", "2", "3")) expect_equal(names(adply(data, c(1, 2), identity)), c("X1", "X2", "V1", "V2", "V3")) expect_equal(names(adply(data, c(1, 3), identity)), c("X1", "X2", "V1", "V2", "V3")) expect_equal(names(adply(data, c(1, 2, 3), identity)), c("X1", "X2", "X3", "V1")) expect_equal(names(adply(data, c(), identity)), paste0("V", data)) expect_equal(names(adply(data, 1, identity, .id = NA)), c("X1", "1", "2", "3")) expect_equal(names(adply(data, 2, identity, .id = NA)), c("X1", "1", "2", "3")) expect_equal(names(adply(data, 3, identity, .id = NA)), c("X1", "1", "2", "3")) expect_equal(names(adply(data, c(1, 2), identity, .id = NA)), c("X1", "X2", "V1", "V2", "V3")) expect_equal(names(adply(data, c(1, 3), identity, .id = NA)), c("X1", "X2", "V1", "V2", "V3")) expect_equal(names(adply(data, c(1, 2, 3), identity, .id = NA)), c("X1", "X2", "X3", "V1")) expect_equal(names(adply(data, c(), identity, .id = NA)), paste0("V", data)) expect_equal(names(adply(data, 1, identity, .id = NULL)), c("1", "2", "3")) expect_equal(names(adply(data, 2, identity, .id = NULL)), c("1", "2", "3")) expect_equal(names(adply(data, 3, identity, .id = NULL)), c("1", "2", "3")) expect_equal(names(adply(data, c(1, 2), identity, .id = NULL)), c("V1", "V2", "V3")) expect_equal(names(adply(data, c(1, 3), identity, .id = NULL)), c("V1", "V2", "V3")) expect_equal(names(adply(data, c(1, 2, 3), identity, .id = NULL)), c("V1")) expect_equal(names(adply(data, c(), identity, .id = NULL)), paste0("V", data)) expect_equal(names(adply(data, 1, identity, .id = LETTERS[1])), c("A", "1", "2", "3")) expect_equal(names(adply(data, 2, identity, .id = LETTERS[1])), c("A", "1", "2", "3")) expect_equal(names(adply(data, 3, identity, .id = LETTERS[1])), c("A", "1", "2", "3")) expect_equal(names(adply(data, c(1, 2), identity, .id = LETTERS[1:2])), c("A", "B", "V1", "V2", "V3")) expect_equal(names(adply(data, c(1, 3), identity, .id = LETTERS[1:2])), c("A", "B", "V1", "V2", "V3")) expect_equal(names(adply(data, c(1, 2, 3), identity, .id = LETTERS[1:3])), c("A", "B", "C", "V1")) error_rx <- "[.]id argument.*number of margins" expect_error(adply(data, 1, identity, .id = LETTERS[1:2]), error_rx) expect_error(adply(data, 2, identity, .id = LETTERS[1:2]), error_rx) expect_error(adply(data, 3, identity, .id = LETTERS[1:2]), error_rx) expect_error(adply(data, c(1, 2), identity, .id = LETTERS[1:3]), error_rx) expect_error(adply(data, c(1, 3), identity, .id = LETTERS[1:3]), error_rx) expect_error(adply(data, c(1, 2, 3), identity, .id = LETTERS[1:4]), error_rx) expect_error(adply(data, c(), identity, .id = LETTERS[1]), error_rx) }) plyr/tests/testthat/test-idf.r0000644000176200001440000000421712034020705016141 0ustar liggesuserscontext("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/tests/testthat/test-data-frame.r0000644000176200001440000000544412511213671017411 0ustar liggesuserscontext("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)) }) # Test for #140 test_that(".id column can be renamed or dropped", { l <- llply(1:4, function(i) rep(i, i)) names(l) <- 1:4 f <- function(l) data.frame(sum=sum(unlist(l))) out1 <- ldply(l, f) out2 <- ldply(l, f, .id='x') out3 <- ldply(l, f, .id=NULL) expect_equal(names(out1), c('.id', 'sum')) expect_equal(names(out2), c('x', 'sum')) expect_equal(names(out3), c('sum')) expect_identical(out1$.id, names(l)) expect_identical(out2$x, factor(names(l))) out4 <- ldply(l, f, .id='sum') # names conflict expect_equal(names(out4), c('sum')) out5 <- ldply(l, f, .id=NA) # defaults expect_equal(names(out5), c('.id', 'sum')) expect_identical(out5$.id, names(l)) out6 <- ldply(l, f, .id='.id') # defaults expect_equal(names(out6), c('.id', 'sum')) expect_identical(out6$.id, factor(names(l))) # no names = no .id column expect_equal(ldply(unname(l), f, .id=NA), out3) expect_equal(ldply(unname(l), f, .id="Name"), out3) expect_equal(ldply(unname(l), f, .id=NULL), out3) # todo: test for list with attr(,'split-labels'), needed? }) plyr/tests/testthat/test-ninteraction.r0000644000176200001440000000345612512025470020105 0ustar liggesuserscontext("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("factor with missing levels has correct count", { id <- id_var(factor(1, NA)) expect_equal(attr(id, "n"), 1) }) test_that("zero length input gives single number", { expect_that(id(character()), is_equivalent_to(integer())) }) 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/tests/testthat/test-rply.r0000644000176200001440000000733612512025470016377 0ustar liggesuserscontext("r?ply") test_that("Side effects for r_ply", { counts <- c(0, 1, 5) # Simple function with side effect of incrementing i in an outer environment # by one inc <- function() { i <<- i + 1; invisible(NULL) } # For each of the possible counts, check that exactly n side effects are seen # for various types of invocations of inc: As a statement, as a function call # or as a function calling the function. Calling r_ply with a function that # returns the inc function should not produce any side effects, this is # intentional. for (n in counts) { i <- 0 r_ply(n, inc) expect_equal(i, n, info="inc") i <- 0 r_ply(n, inc()) expect_equal(i, n, info="inc()") i <- 0 r_ply(n, inc() + inc()) expect_equal(i, 2 * n, info="inc() + inc()") i <- 0 r_ply(n, function() inc()) expect_equal(i, n, info="function() inc()") i <- 0 r_ply(n, function() inc() + inc()) expect_equal(i, 2 * n, info="function() inc() + inc()") i <- 0 r_ply(n, function() inc) expect_equal(i, 0, info="function() inc") } }) test_that("Side effects for rlply", { counts <- c(0, 1, 5) # Similar to the test for r_ply, now there is also a return value in incition # to the side effect inc <- function() { i <<- i + 1 } # The test now checks, in incition to side effect count, that the returned # list is correct for (n in counts) { i <- 0 res <- rlply(n, inc) expect_equal(res, as.list(seq_len(n)), info="inc") expect_equal(i, n, info="inc") i <- 0 res <- rlply(n, inc()) expect_equal(res, as.list(seq_len(n)), info="inc()") expect_equal(i, n, info="inc()") i <- 0 res <- rlply(n, function() inc()) expect_equal(res, as.list(seq_len(n)), info="function() inc()") expect_equal(i, n, info="function() inc()") # Funny case: A function that returns a function, this is not # handled at all i <- 0 rlply(n, function() inc) expect_equal(i, 0, info="function() inc") } }) test_that("Side effects for raply", { counts <- c(0, 1, 5) inc <- function() { i <<- i + 1 } for (n in counts) { # This is funny. Why does raply(.n, inc) return a named vector only for # .n == 1? if (n == 0) { exp_res <- logical() } else if (n == 1) { exp_res <- setNames(nm = 1) } else exp_res <- seq_len(n) i <- 0 res <- raply(n, inc) expect_equal(res, exp_res, info="inc") expect_equal(i, n, info="inc") i <- 0 res <- raply(n, inc()) expect_equal(res, exp_res, info="inc()") expect_equal(i, n, info="inc()") i <- 0 res <- raply(n, function() inc()) expect_equal(res, exp_res, info="function() inc()") expect_equal(i, n, info="function() inc()") } }) test_that("Side effects for rdply", { counts <- c(0, 1, 5) inc <- function() { i <<- i + 1; data.frame(i = i) } for (n in counts) { if (n == 0) { exp_res <- data.frame() } else { exp_res <- data.frame(.n = 1L:n, i = 1L:n, stringsAsFactors = FALSE) } i <- 0 res <- rdply(n, inc) expect_equal(res, exp_res, info="inc") expect_equal(i, n, info="inc") i <- 0 res <- rdply(n, inc()) expect_equal(res, exp_res, info="inc()") expect_equal(i, n, info="inc()") i <- 0 res <- rdply(n, function() inc()) expect_equal(res, exp_res, info="function() inc()") expect_equal(i, n, info="function() inc()") } }) test_that("Invalid arguments for r_ply", { expect_error(r_ply(-3, identity)) expect_error(r_ply("abc", identity)) expect_error(r_ply(c(1,2), identity)) expect_error(r_ply(list(5), identity)) }) test_that(".id column for rdply", { expect_equal(rdply(5, 10)$.n, 1:5) expect_equal(rdply(5, 10, .id=".x")$.x, 1:5) }) plyr/tests/testthat/test-arrange.r0000644000176200001440000000034512512025470017021 0ustar liggesuserscontext("Arrange") test_that("bogus sort order", { expect_error(arrange(mtcars, diff(mpg)), "Length of ordering vectors") }) test_that("descending sort", { expect_equal(arrange(mtcars, desc(mpg)), arrange(mtcars, -mpg)) }) plyr/tests/testthat/test-array.r0000644000176200001440000001533013573505362016533 0ustar liggesuserscontext("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_equivalent(rowMeans(a), aaply(a, 1, mean)) expect_equivalent(colMeans(a), aaply(a, 2, mean)) b <- structure(a, dimnames = amv_dimnames(a)) expect_equivalent(rowMeans(b), aaply(b, 1, mean)) expect_equivalent(colMeans(b), aaply(b, 2, mean)) }) 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) } }) test_that("no support for duplicate names (#211)", { n <- function(x) { setNames(x, letters[c(1:9,2)]) } B <- list(X=n(1:10), Y=n(11:20), Z=n(21:30)) expect_warning(laply(B, identity), "Duplicate names") AB <- c('a', 'b', 'a', 'b') ABCD <- c('a', 'b', 'c', 'd') ar <- array(rep(rep(rep(1:4, 4), 4), 2), dim=c(4, 4, 2), dimnames=list(ABCD, ABCD, c('i', 'ii'))) ar[,,2] <- ar[,,2]+4 dimnames(ar)[1:2] <- list(AB, AB) if (getRversion() >= "3.4.0") { expect_warning(expect_error(aaply(ar, 3, identity), "duplicated")) } else { expect_warning(aaply(ar, 3, identity), "Duplicate names") } }) plyr/tests/testthat/test-split-indices.r0000644000176200001440000000075212506324547020165 0ustar liggesuserscontext("Split indices") test_that("Error if n too small", { expect_error(split_indices(1:10, -5), "n must be") }) test_that("index expands if n too small", { expect_equal(split_indices(1:10, 5), as.list(1:10)) }) test_that("n is optional in split indices", { x <- sample(100) a <- split_indices(x) b <- split_indices(x, 100) expect_equal(a, b) }) test_that("succeeds for large number of groups", { i <- 2097142 expect_equal(length(split_indices(seq_len(i), i)), i) }) plyr/tests/testthat/test-revalue.r0000644000176200001440000001211012725616513017050 0ustar liggesuserscontext("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 - uses first instance, and gives 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 (for factors, levels are 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) }) test_that("revalue and mapvalues respect warn_missing", { # revalue expect_message(revalue("a", c("a"="A")), NA) expect_message(revalue("a", c("b"="B"), warn_missing=TRUE)) expect_message(revalue("a", c("b"="B"), warn_missing=FALSE), NA) # mapvalues expect_message(mapvalues("a", "a", "A"), NA) expect_message(mapvalues("a", "b", "B", warn_missing=TRUE)) expect_message(mapvalues("a", "b", "B", warn_missing=FALSE), NA) # mapvalues with factors expect_message(mapvalues(factor("a"), "a", "A"), NA) expect_message(mapvalues(factor("a"), "b", "B", warn_missing=TRUE)) expect_message(mapvalues(factor("a"), "b", "B", warn_missing=FALSE), NA) }) plyr/tests/testthat/quickdf.r0000644000176200001440000000022612034574152016056 0ustar liggesuserscontext("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/tests/testthat/test-count.r0000644000176200001440000000342513627304674016552 0ustar liggesuserslibrary(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)) }) test_that("count works with factors and dates", { genders <- c("Female", "Male") n <- c(5, 10) gender_data <- factor(rep.int(genders, n)) expect_equal( count(gender_data), data.frame(x = genders, freq = n, stringsAsFactors = TRUE) ) this_week <- seq(Sys.Date(), Sys.Date() + 6, "1 day") n2 <- 1:7 day_data <- rep(this_week, n2) expect_equal(count(day_data), data.frame(x = this_week, freq = n2)) }) test_that("vaggregate corner cases", { res <- vaggregate(1:99, rep(1:11, 9), sum) expect_equal(res, vaggregate(1:99, expand.grid(1:11, 1:9)[,1,drop=FALSE], sum)) expect_equal(res, vaggregate(1:99, rep(0.5 + (1:11), 9), sum, .default = 1)) }) plyr/tests/testthat/test-split-data-frame.r0000644000176200001440000000114512034617313020535 0ustar liggesuserscontext("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/tests/testthat/test-list.r0000644000176200001440000000234012512025470016352 0ustar liggesuserscontext("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])) }) # Test for #142 test_that(".n column can be renamed or dropped", { f <- function() data.frame(r=runif(1)) out1 <- rdply(4, f) out2 <- rdply(4, f, .id='x') expect_equal(names(out1), c('.n', 'r')) expect_equal(names(out2), c('x', 'r')) # more testing expect_identical(out1$.n, seq_len(4)) expect_identical(out2$x, seq_len(4)) out <- rdply(4, f, .id=NULL) expect_equal(names(out), c('r')) expect_false(out$r[4] == 4) out <- rdply(4, f, .id='r') # names conflict expect_equal(names(out), c('r')) out <- rdply(4, f, .id='.n') # defaults expect_equal(names(out), c('.n', 'r')) expect_identical(out$.n, seq_len(4)) }) plyr/tests/testthat/test-parallel.r0000644000176200001440000000213712725616571017215 0ustar liggesuserscontext("Parallel") with_parallel <- function(code) { skip_on_cran() skip_if_not_installed("doParallel") doParallel::registerDoParallel(cores = 2) on.exit(doParallel::stopImplicitCluster()) code } # test_that("l_ply respects .parallel", { # with_parallel( # expect_that( # l_ply(c(0.1, 0.1), Sys.sleep, .parallel = TRUE), # takes_less_than(0.18)) # ) # }) test_that("l_ply + .parallel complains about invalid arguments", { with_parallel({ 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("llply + .parallel complains about invalid arguments", { with_parallel({ expect_message( llply(1:10, force, .parallel = TRUE, .progress = "text"), "Progress disabled") }) }) test_that(".paropts passes options to foreach", { combine <- function(a, b) NULL with_parallel(x <- llply(1:10, identity, .parallel = TRUE, .paropts = list(.combine = combine))) expect_equal(x, NULL) }) plyr/tests/testthat/test-progress.r0000644000176200001440000000027712506322163017254 0ustar liggesuserscontext("Progress bars") test_that("unknown progress bar raised warning, not error", { expect_warning( llply(1:10, identity, .progress = "blah"), "Cannot find progress bar" ) }) plyr/tests/testthat/test-simplify-df.r0000644000176200001440000001132212512025470017622 0ustar liggesuserscontext("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(c = 5:15, b = 5:10, a = 1:5) df <- ldply(li, function(x) mean(x)) expect_that(df$.id, equals(names(li))) df <- ldply(li, function(x) { if (any(x >= 10)) mean(x) }) expect_that(df$.id, equals(names(li)[-3])) }) 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, without id column", { 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("a", "b", "c", "d")) }) test_that("matrices converted to data frames, with id column", { mat <- matrix(1:20, ncol = 4) colnames(mat) <- letters[1:4] li <- list(a = mat, b = mat) df <- plyr:::list_to_dataframe(li, id_name = "my_id") expect_equal(nrow(df), 2 * nrow(mat)) expect_equal(names(df), c("my_id", "a", "b", "c", "d")) expect_equal(df$my_id, rep(c("a", "b"), c(5, 5))) }) test_that("matrices converted to data frames, with id column as factor", { mat <- matrix(1:20, ncol = 4) colnames(mat) <- letters[1:4] li <- list(a = mat, b = mat) df <- list_to_dataframe(li, id_name = "my_id", id_as_factor = TRUE) expect_equal(nrow(df), 2 * nrow(mat)) expect_equal(names(df), c("my_id", "a", "b", "c", "d")) expect_equal(levels(df$my_id), c("a", "b")) }) plyr/tests/testthat/test-replicate.r0000644000176200001440000000046312512025470017353 0ustar liggesuserscontext("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) }) test_that("name of id column is set", { df <- rdply(4, function() c(a=1), .id='index') expect_equal(names(df), c('index', 'a')) }) plyr/tests/testthat/test-manip.r0000644000176200001440000000705112512025470016507 0ustar liggesuserscontext("Manipulation") test_that("each() function", { expect_equal(each(min, max)(1:10), c(min=1, max=10)) expect_equal(each(c(min, max))(1:10), c(min=1, max=10)) expect_equal(each(top=max, bottom=min)(1:10), c(top=10, bottom=1)) expect_equal(each(top=max, min)(1:10), c(top=10, min=1)) expect_equal(each(top="max", "min")(1:10), c(top=10, min=1)) expect_equal(each(c("min", max))(1:10), c(min=1, max=10)) # Odd behavior, kept for compatibility: expect_equal(each(pmin)(1:10, 10:1), c(1:5, 5:1)) expect_equal(each(max, pmin)(1:10, 10:1), c(max=10, pmin=c(1:5, 5:1))) expect_error(each()(1:10)) }) test_that("here() function", { df <- data.frame(a = rep(c("a","b"), each = 10), b = 1:20) f1 <- function(label) { ddply(df, "a", mutate, label = paste(label, b)) } expect_error(f1("name:")) f2 <- function(label) { ddply(df, "a", here(mutate), label = paste(label, b)) } expect_true(all(grepl("^name: ", f2("name:")$label))) f3 <- function() { label <- "name:" ddply(df, "a", here(mutate), label = paste(label, b)) } expect_true(all(grepl("^name: ", f3()$label))) }) test_that("defaults() function", { expect_equal(defaults(c(a=1, b=2), c(c=3)), c(a=1, b=2, c=3)) expect_equal(defaults(c(a=1, b=2), c(a=3, b=4)), c(a=1, b=2)) expect_equal(defaults(c(a=1, b=2), c(a=3, d=4)), c(a=1, b=2, d=4)) expect_equal(defaults(c(a=1, b=2), c()), c(a=1, b=2)) expect_equal(defaults(c(), c(a=3, d=4)), c(a=3, d=4)) }) test_that("as.data.frame.function() function", { expect_equal(as.data.frame(identity)(1:10), data.frame(value = 1:10)) expect_equal(as.data.frame(rev)(1:10), data.frame(value = 10:1)) # Always create value column, even if empty expect_equal(as.data.frame(identity)(numeric()), data.frame(value = numeric())) }) test_that("name_rows() function", { expect_equal(name_rows(baseball)$.rownames, rownames(baseball)) expect_equal(rownames(name_rows(name_rows(baseball))), rownames(baseball)) }) test_that("round_any() function", { expect_equal(round_any(135, 10), 140) expect_equal(round_any(135, 100), 100) expect_equal(round_any(135, 25), 125) expect_equal(round_any(135, 10, floor), 130) expect_equal(round_any(135, 100, floor), 100) expect_equal(round_any(135, 25, floor), 125) expect_equal(round_any(135, 10, ceiling), 140) expect_equal(round_any(135, 100, ceiling), 200) expect_equal(round_any(135, 25, ceiling), 150) expect_equal(round_any(as.POSIXct("2000-01-01 11:00:00", tz="UTC"), 86400), as.POSIXct("2000-01-01", tz="UTC")) expect_equal(round_any(as.POSIXct("2000-01-01 11:11:11", tz="UTC"), 3600), as.POSIXct("2000-01-01 11:00", tz="UTC")) expect_equal(round_any(as.POSIXct("2000-01-01 11:11:11", tz="UTC"), 10, ceiling), as.POSIXct("2000-01-01 11:11:20", tz="UTC")) }) test_that("take() function", { x <- array(seq_len(3 * 4 * 5), c(3, 4, 5)) expect_equal(take(x, 3, 1), x[,,1, drop = FALSE]) expect_equal(take(x, 2, 1), x[,1,, drop = FALSE]) expect_equal(take(x, 1, 1), x[1,,, drop = FALSE]) expect_equal(take(x, 3, 1, drop = TRUE), x[,,1]) expect_equal(take(x, 2, 1, drop = TRUE), x[,1,]) expect_equal(take(x, 1, 1, drop = TRUE), x[1,,]) expect_equal(take(x, 1:3, 3:5), x[3,4,5, drop = FALSE]) expect_equal(take(x, 1:2, 2:3), x[2,3,, drop = FALSE]) expect_equal(take(x, 2:3, 1:2), x[,1,2, drop = FALSE]) # Odd behavior, tested for compatibility: expect_equal(take(x, 1:3, 1), x[1,1,1, drop = FALSE]) expect_equal(take(x, 1:2, 1), x[1,1,, drop = FALSE]) expect_equal(take(x, 2:3, 1), x[,1,1, drop = FALSE]) }) plyr/tests/testthat/test-rbind.matrix.r0000755000176200001440000000723213573504774020031 0ustar liggesuserscontext("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(dim(ba), c(0, 2)) expect_true(all(colnames(ba) %in% c("x", "y"))) expect_equal(dim(bb), c(2, 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(dim(bc), c(0, 3)) expect_true(all(colnames(bc) %in% c("x", "y", "z"))) }) plyr/tests/testthat/test-summarise.r0000644000176200001440000000067412512025470017414 0ustar liggesuserscontext("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), mvs = mean(vs)) expect_that(names(df), equals(c("mean(cyl)", "mvs"))) }) plyr/tests/testthat/test-utils.r0000644000176200001440000000106212512025470016537 0ustar liggesuserscontext("Utilities") test_that("is.discrete", { expect_true(is.discrete(factor(3))) expect_true(is.discrete("3")) expect_true(is.discrete(TRUE)) expect_false(is.discrete(3L)) expect_false(is.discrete(3.0)) expect_false(is.discrete(identity)) }) test_that("nunique", { expect_equal(nunique(LETTERS), 26) expect_equal(nunique(factor(LETTERS)), 26) # Odd behavior, for compatibility reasons: expect_equal(nunique(factor(LETTERS)[1:3]), 26) }) test_that("check for formula", { expect_true(is.formula(~a)) expect_false(is.formula("a")) }) plyr/tests/testthat.R0000644000176200001440000000006412506322574014373 0ustar liggesuserslibrary(testthat) library(plyr) test_check("plyr") plyr/src/0000755000176200001440000000000013627315360012035 5ustar liggesusersplyr/src/loop_apply.c0000644000176200001440000000107012560701042014344 0ustar liggesusers#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/src/split-numeric.cpp0000644000176200001440000000174512506324622015337 0ustar liggesusers#include using namespace Rcpp; //' Split indices. //' //' An optimised version of split for the special case of splitting row //' indices into groups, as used by \code{\link{splitter_d}}. //' //' @param index integer indices //' @param n largest integer (may not appear in index). This is hint: if //' the largest value of \code{group} is bigger than \code{n}, the output //' will silently expand. //' @useDynLib plyr //' @keywords internal manip //' @export //' @examples //' split_indices(sample(10, 100, rep = TRUE)) //' split_indices(sample(10, 100, rep = TRUE), 10) // [[Rcpp::export]] std::vector > split_indices(IntegerVector group, int n = 0) { if (n < 0) stop("n must be a positive integer"); std::vector > ids(n); int nx = group.size(); for (int i = 0; i < nx; ++i) { // group is 1-indexed if (group[i] > (int) ids.size()) { ids.resize(group[i]); } ids[group[i] - 1].push_back(i + 1); } return ids; } plyr/src/RcppExports.cpp0000644000176200001440000000177113573503412015035 0ustar liggesusers// Generated by using Rcpp::compileAttributes() -> do not edit by hand // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #include using namespace Rcpp; // split_indices std::vector > split_indices(IntegerVector group, int n); RcppExport SEXP _plyr_split_indices(SEXP groupSEXP, SEXP nSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< IntegerVector >::type group(groupSEXP); Rcpp::traits::input_parameter< int >::type n(nSEXP); rcpp_result_gen = Rcpp::wrap(split_indices(group, n)); return rcpp_result_gen; END_RCPP } RcppExport SEXP loop_apply_(SEXP, SEXP, SEXP); static const R_CallMethodDef CallEntries[] = { {"_plyr_split_indices", (DL_FUNC) &_plyr_split_indices, 2}, {"loop_apply_", (DL_FUNC) &loop_apply_, 3}, {NULL, NULL, 0} }; RcppExport void R_init_plyr(DllInfo *dll) { R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } plyr/R/0000755000176200001440000000000013627315360011447 5ustar liggesusersplyr/R/dlply.r0000644000176200001440000000221412506330463012751 0ustar liggesusers#' 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. #' To apply a function for each row, use \code{\link{alply}} with #' \code{.margins} set to \code{1}. #' #' @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/vaggregate.r0000644000176200001440000000401312560701400013731 0ustar liggesusers#' 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.out = 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/indexed.r0000644000176200001440000000110212512025470013234 0ustar liggesusers#' @export length.indexed <- function(x) length(x$index) #' @export names.indexed <- function(x) { labels <- attr(x, "split_labels") labels[] <- lapply(labels, as.character) do.call(paste, c(labels, list(sep = "."))) } #' @export 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 } #' @export print.indexed <- function(x, ...) { print(as.list(x)) } #' @export "[.indexed" <- function(x, ...) { as.list(x)[...] } plyr/R/defaults.r0000644000176200001440000000037612034020705013432 0ustar liggesusers#' 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/rbind-fill.r0000644000176200001440000001571013401770212013647 0ustar liggesusers#' 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. #' #' Unordered factor columns will have their levels unified and #' character data bound with factors will be converted to #' character. POSIXct data will be converted to be in the same time #' zone. Array and matrix columns must have identical dimensions after #' the row count. Aside from these there are no general checks that #' each column is of consistent data type. #' #' @param ... input data frames to row bind together. The first argument can #' be a list of data frames, in which case all other arguments are ignored. #' Any NULL inputs are silently dropped. If all inputs are NULL, the output #' is NULL. #' @keywords manip #' @family binding functions #' @return a single data frame #' @export rbind.fill #' @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]] } dfs <- compact(dfs) 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 ot <- output_template(dfs, nrows) setters <- ot$setters getters <- ot$getters # Case of zero column inputs if (length(setters) == 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.out = pos[i, 2]) df <- dfs[[i]] for (var in names(df)) { setters[[var]](rng, df[[var]]) # nolint } } quickdf(lapply(getters, function(x) x())) } # Construct named lists of setters and getters. output_template <- function(dfs, nrows) { vars <- unique(unlist(lapply(dfs, base::names))) # ~ 125,000/s output <- vector("list", length(vars)) names(output) <- vars seen <- rep(FALSE, length(output)) names(seen) <- vars for (df in dfs) { matching <- intersect(names(df), vars[!seen]) for (var in matching) { output[[var]] <- allocate_column(df[[var]], nrows, dfs, var) } seen[matching] <- TRUE if (all(seen)) break # Quit as soon as all done } list(setters=lapply(output, `[[`, "set"), getters=lapply(output, `[[`, "get")) } # Allocate space for a column to be filled out by rbind.fill. # # @param example An example vector taken from the first data frame # @param nrows The number of rows # @param dfs The list of data frames that will be combined. This may # need to be scanned (to unify factor levels or check array dimension # consistency) # @param var The name of the column. # # @return A list of two accessor functions `list(set=<>, get=<>)`. # `.$set(rows, value)` stores data in the given rows. # `.$get()` retreives the column data. allocate_column <- function(example, nrows, dfs, var) { #Compute the attributes of the column and allocate. Returns a #mutator function f(rows, values) rather than the actual allocated #column. a <- attributes(example) type <- typeof(example) class <- a$class isList <- is.recursive(example) a$names <- NULL a$class <- NULL if (is.data.frame(example)) { stop("Data frame column '", var, "' not supported by rbind.fill") } if (is.array(example)) { if (length(dim(example)) > 1) { if ("dimnames" %in% names(a)) { a$dimnames[1] <- list(NULL) if (!is.null(names(a$dimnames))) names(a$dimnames)[1] <- "" } # Check that all other args have consistent dims df_has <- vapply(dfs, function(df) var %in% names(df), FALSE) dims <- unique(lapply(dfs[df_has], function(df) dim(df[[var]])[-1])) if (length(dims) > 1) stop("Array variable ", var, " has inconsistent dims") a$dim <- c(nrows, dim(example)[-1]) length <- prod(a$dim) } else { #1d arrays devolve into vectors a$dim <- NULL a$dimnames <- NULL length <- nrows } } else { length <- nrows } if (is.factor(example)) { df_has <- vapply(dfs, function(df) var %in% names(df), FALSE) isfactor <- vapply(dfs[df_has], function(df) is.factor(df[[var]]), FALSE) if (all(isfactor)) { #will be referenced by the mutator levels <- unique(unlist(lapply(dfs[df_has], function(df) levels(df[[var]])))) a$levels <- levels handler <- "factor" } else { #fall back on character type <- "character" handler <- "character" class <- NULL a$levels <- NULL } } else if (inherits(example, "POSIXt")) { tzone <- attr(example, "tzone") class <- c("POSIXct", "POSIXt") type <- "double" handler <- "time" } else { handler <- type } column <- vector(type, length) if (!isList) { column[] <- NA } attributes(column) <- a #construct an assignment expression like `column[rows, ...] <- what` #appropriate for the number of dims assignment <- make_assignment_call(length(a$dim)) #It is especially important never to inspect the column when in the #main rbind.fill loop. To avoid that, we've done specialization #(figuring out the array assignment form and data type) ahead of #time, and instead of returning the column, we return accessor #functions that close over the column. setter <- switch( handler, character = function(rows, what) { what <- as.character(what) eval(assignment) }, factor = function(rows, what) { #duplicate what `[<-.factor` does what <- match(what, levels) #no need to check since we already computed levels eval(assignment) }, time = function(rows, what) { what <- as.POSIXct(what, tz = tzone) eval(assignment) }, function(rows, what) { eval(assignment) }) getter <- function() { class(column) <<- class column } list(set=setter, get=getter) } #construct an assignment expression like `column[rows, ...] <- what` #appropriate for the number of dims make_assignment_call <- function(ndims) { assignment <- quote(column[rows] <<- what) if (ndims >= 2) { assignment[[2]] <- as.call( c(as.list(assignment[[2]]), rep(list(quote(expr = )), ndims - 1))) } assignment } plyr/R/idataframe.r0000644000176200001440000000512012512025470013715 0ustar liggesusers#' 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 #' @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")) } #' @export "[.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")) } #' @export names.idf <- function(x) x$`_cols` #' @export dim.idf <- function(x) c(length(x$`_rows`), length(x$`_cols`)) #' @export as.data.frame.idf <- function(x, ...) { x$`_data`[x$`_rows`, x$`_cols`] } #' @export "[[.idf" <- function(x, i) { if (is.numeric(i)) { i <- names(x)[i] } x$`_data`[[i]][x$`_rows`] } # "[[<-.idf" <- "[<-.idf" <- function(...) stop("Immutable") plyr/R/plyr.r0000644000176200001440000000550413573504334012625 0ustar liggesusers#' 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 #' @importFrom Rcpp sourceCpp #' @useDynLib plyr, .registration = TRUE #' @name plyr # EXCLUDE COVERAGE START NULL .onUnload <- function (libpath) { library.dynam.unload("plyr", libpath) } # EXCLUDE COVERAGE END plyr/R/list-to-array.r0000644000176200001440000000416612512025504014336 0ustar liggesusers#' 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]]) if (any(vapply(res_labels, anyDuplicated, integer(1)) != 0)) { warning("Duplicate names not supported.", call. = FALSE) } 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), na.last = TRUE)) 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/join-all.r0000644000176200001440000000110212512025470013321 0ustar liggesusers#' 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/laply.r0000644000176200001440000000230412043515037012744 0ustar liggesusers#' 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/data-frame.r0000644000176200001440000000144312512025470013625 0ustar liggesusers#' Make a function return a data frame. #' #' Create a new function that returns the existing function wrapped in a #' data.frame with a single column, \code{value}. #' #' 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. #' The \code{value} column is always created, even for empty inputs. #' #' @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, ...) { function(...) data.frame(value = x(...)) } plyr/R/rlply.r0000644000176200001440000000743312512025470012773 0ustar liggesusers#' 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") { res <- .rlply_worker(.n, .progress, eval.parent(substitute(function() .expr))) res } .rlply_worker <- function(.n, .progress, .expr_wrap, .print = FALSE, .discard = FALSE) { if (!is.vector(.n, "numeric") || length(.n) > 1L) stop(".n must be an integer vector of length 1") if (.n == 0L) return (list()) progress <- create_progress_bar(.progress) progress$init(.n) on.exit(progress$term()) if (.print) { wrap <- function(f) function() { print(f()) } } else { wrap <- identity } # The logic below is responsible for ascertaining that .expr is evaluated # exactly .n times, whether it's a function or an expression. (See GitHub # issue #158.) When the function .rlply_worker is called, the .expr_wrap # argument is a function that returns the .expr argument passed to the calling # r*ply function. The .wrapped_expr_to_fun function will convert the # .expr_wrap argument to a list that contains a function and the result of the # first evaluation, which is necessary because there seems to be no other way # to find out if .expr is a function or an expression without evaluating it at # least once. After that, only .n - 1 further evaluations are necessary. # # In addition, results are printed and/or discareded depending on the `wrap` # function defined above. fun <- .wrapped_expr_to_fun(.expr_wrap) f <- wrap(fun$f) if (.discard) { wrap(function() fun$val)() progress$step() for (i in seq.int(from = 2L, length.out = .n - 1L)) { f() progress$step() } invisible(NULL) } else { result <- vector("list", length = .n) result[1L] <- list(wrap(function() fun$val)()) progress$step() for (i in seq.int(from = 2L, length.out = .n - 1L)) { result[i] <- list(f()) progress$step() } result } } #' r*ply helper function #' #' Call a function to check if the result is a function or an expression, to #' support expressions as arguments to the r*ply family. #' #' @param .expr_wrap function to call #' @return named list with two components. f -- function, val -- result of first #' evaluation #' @noRd .wrapped_expr_to_fun <- function(.expr_wrap) { # When .expr_wrap is evaluated, it will return either a function or an # expression. In the first case, this function is assigned to the f # component, and also called once explicitly to assign the val component. In # the second case, this has been already the first evaluation of .expr -- the # parameter wrapped by .expr_wrap; the results are reused for the val # component, and the wrapped function is assigned to f. res <- .expr_wrap() if (is.function(res)) { list(f = res, val = res()) } else { list(f = .expr_wrap, val = res) } } plyr/R/alply.r0000644000176200001440000000304512167213765012761 0ustar liggesusers#' 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/revalue.r0000644000176200001440000000633012303221212013255 0ustar liggesusers#' 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, warn_missing) 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/try.r0000644000176200001440000000317312512025470012444 0ustar liggesusers#' 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) #' @export #' @keywords internal #' @seealso \code{\link{tryapply}} try_default <- function(expr, default, quiet = FALSE) { result <- default if (quiet) { tryCatch(result <- expr, error = function(e) NULL) } else { try(result <- expr) } result } #' @rdname try_default #' @export tryNULL <- function(expr) try_default(expr, NULL, quiet = TRUE) #' Apply with built in try. #' Uses compact, lapply and tryNULL #' #' @param list list to apply function \code{f} on #' @param f function #' @param ... further arguments to \code{f} #' @keywords internal #' @export tryapply <- function(list, fun, ...) { compact(lapply(list, function(x) tryNULL(fun(x, ...)))) } plyr/R/join.r0000644000176200001440000001270012512025470012561 0ustar liggesusers#' 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) } 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 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/splitter-a.r0000644000176200001440000000700712512025504013710 0ustar liggesusers#' 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. #' @param .id names of the split label. #' Pass \code{NULL} to avoid creation of split labels. #' Omit or pass \code{NA} to use the default names #' \code{"X1"}, \code{"X2"}, \ldots. #' Otherwise, this argument must have the same length as #' \code{.margins}. #' @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, .id = NA) { .margins <- as.integer(.margins) if (!is.null(.id)) { if (any(is.na(.id))) { .id <- paste("X", seq_along(.margins), sep="") } else { if (length(.id) != length(.margins)) { stop(".id argument must be of length ", length(.margins), " (=number of margins)") } .id <- as.character(.id) } } 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", seq_len(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) if (any(vapply(dnames, anyDuplicated, integer(1)) != 0)) { warning("Duplicate names not supported.", call. = FALSE) } 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) <- .id } if (is.null(.id)) split_labels <- NULL } structure( il, class = c(class(il), "split", "list"), split_type = "array", split_labels = split_labels ) } plyr/R/indexed-data-frame.r0000644000176200001440000000225212303221212015230 0ustar liggesusers#' 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") ) } #' @export "[[.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/splitter-d.r0000644000176200001440000000575612303221212013714 0ustar liggesusers#' 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)) { x <- addNA(x, ifany = TRUE) levs <- levels(x) factor(levs, levels = levs) } else { sort(unique(x)) } } plyr/R/d_ply.r0000644000176200001440000000135012506330463012734 0ustar liggesusers#' Split data frame, apply function, and discard results. #' #' For each subset of a data frame, apply function and discard results. #' To apply a function for each row, use \code{\link{a_ply}} with #' \code{.margins} set to \code{1}. #' #' @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/ddply.r0000644000176200001440000000352612506330463012750 0ustar liggesusers#' 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. #' To apply a function for each row, use \code{\link{adply}} with #' \code{.margins} set to \code{1}. #' #' @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 #' 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/utils.r0000644000176200001440000000336712512025470012773 0ustar liggesusers#' 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) } #' Is a formula? #' Checks if argument is a formula #' #' @keywords internal #' @export is.formula <- function(x) inherits(x, "formula") "%||%" <- 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/progress-time.r0000644000176200001440000000407412725616016014437 0ustar liggesusers#' 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) utils::setTxtProgressBar(txt, 0) }, step = function() { n <<- n + 1 utils::setTxtProgressBar(txt, n) }, term = function() close(txt) ) } txtTimerBar <- function(n = 1) { # nolint start start <- .last_update_time <- proc.time()[3] times <- numeric(n) # nolint end 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 = "") utils::flush.console() } str_rep <- function(x, i) { paste(rep.int(x, i), collapse = "") } plyr/R/plyr-deprecated.r0000644000176200001440000000053712512025470014713 0ustar liggesusers#' Deprecated Functions in Package plyr #' #' These functions are provided for compatibility with older versions of #' \code{plyr} only, and may be defunct as soon as the next release. #' #' \itemize{ #' \item \code{\link{liply}} #' \item \code{\link{isplit2}} #' } #' #' @name plyr-deprecated # EXCLUDE COVERAGE START NULL # EXCLUDE COVERAGE END plyr/R/data.r0000644000176200001440000000607212034020705012533 0ustar liggesusers#' 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/raply.r0000644000176200001440000000313512303221212012741 0ustar liggesusers#' 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) { res <- .rlply_worker(.n, .progress, eval.parent(substitute(function() .expr))) list_to_array(res, NULL, .drop) } plyr/R/match-df.r0000644000176200001440000000337012034576574013327 0ustar liggesusers#' 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/mlply.r0000644000176200001440000000156112035653743012774 0ustar liggesusers#' 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/dimensions.r0000644000176200001440000000247012512025470013775 0ustar liggesusers#' 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/split.r0000644000176200001440000000203212034020705012745 0ustar liggesusers#' 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/daply.r0000644000176200001440000000372712506330463012750 0ustar liggesusers#' 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}}. #' To apply a function for each row, use \code{\link{aaply}} with #' \code{.margins} set to \code{1}. #' #' @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/list-to-dataframe.r0000644000176200001440000000416112303221212015127 0ustar liggesusers#' 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 #' @param idname the name of the index column, \code{NULL} for no index #' column #' @keywords internal list_to_dataframe <- function(res, labels = NULL, id_name = NULL, id_as_factor = FALSE) { null <- vapply(res, is.null, logical(1)) res <- res[!null] if (length(res) == 0) return(data.frame()) if (!is.null(labels)) { stopifnot(nrow(labels) == length(null)) labels <- labels[!null, , drop = FALSE] } names_res <- names(res) if (!is.null(id_name) && is.null(labels) && !is.null(names_res)) { stopifnot(length(id_name) == 1) if (id_as_factor) names_res <- factor(names_res, levels = unique(names_res)) labels <- data.frame(.id = names_res, stringsAsFactors = FALSE) names(labels) <- id_name } # Figure out how to turn elements into a data frame 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/parallel.r0000644000176200001440000000061212512025470013415 0ustar liggesuserssetup_parallel <- function() { if (!requireNamespace("foreach", quietly = TRUE)) { # EXCLUDE COVERAGE START stop("foreach package required for parallel plyr operation", call. = FALSE) # EXCLUDE COVERAGE END } if (foreach::getDoParWorkers() == 1) { # EXCLUDE COVERAGE START warning("No parallel backend registered", call. = TRUE) # EXCLUDE COVERAGE END } } plyr/R/summarise.r0000644000176200001440000000337712512025470013641 0ustar liggesusers#' Summarise a data frame. #' #' Summarise works in an analogous way to \code{\link{mutate}}, except #' instead of adding columns to an existing data frame, it creates a new #' data frame. This is particularly useful in conjunction with #' \code{\link{ddply}} as it makes it easy to perform group-wise summaries. #' #' @param .data the data frame to be summarised #' @param ... further arguments of the form var = value #' @keywords manip #' @aliases summarise summarize #' @export summarise summarize #' @note Be careful when using existing variable names; the corresponding #' columns will be immediately updated with the new data and this can affect #' subsequent operations referring to those variables. #' @examples #' # Let's extract the number of teams and total period of time #' # covered by the baseball dataframe #' 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))) # nolint 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/rbind-fill-matrix.r0000644000176200001440000000470613573504153015165 0ustar liggesusers#' 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 rbind.fill.matrix #' @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.out = pos[i, 2]) output[rng, lcols[[i]]] <- matrices[[i]] } output } plyr/R/quote.r0000644000176200001440000001362112725616027012774 0ustar liggesusers#' 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 #' @export print.quoted <- function(x, ...) utils::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 #' @export 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[=quoted]{.}} #' @param x input to quote #' @param env environment in which unbound symbols in expression should be #' evaluated. Defaults to the environment in which \code{as.quoted} was #' 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") #' @export as.quoted.call <- function(x, env = parent.frame()) { structure(as.list(x)[-1], env = env, class = "quoted") } #' @export as.quoted.character <- function(x, env = parent.frame()) { structure( lapply(x, function(x) parse(text = x)[[1]]), env = env, class = "quoted" ) } #' @export as.quoted.numeric <- function(x, env = parent.frame()) { structure(x, env = env, class = c("quoted", "numeric")) } #' @export 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") } #' @export as.quoted.quoted <- function(x, env = parent.frame()) x #' @export as.quoted.NULL <- function(x, env = parent.frame()) { structure(list(), env = env, class = "quoted") } #' @export as.quoted.name <- function(x, env = parent.frame()) { structure(list(x), env = env, class = "quoted") } #' @export as.quoted.factor <- function(x, env = parent.frame()) { as.quoted(as.character(x), env) } #' @export c.quoted <- function(..., recursive = FALSE) { structure(NextMethod("c"), class = "quoted", env = attr(list(...)[[1]], "env")) } #' @export "[.quoted" <- function(x, i, ...) { structure(NextMethod("["), env = attr(x, "env"), class = "quoted") } plyr/R/RcppExports.R0000644000176200001440000000135113627312245014062 0ustar liggesusers# Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #' Split indices. #' #' An optimised version of split for the special case of splitting row #' indices into groups, as used by \code{\link{splitter_d}}. #' #' @param index integer indices #' @param n largest integer (may not appear in index). This is hint: if #' the largest value of \code{group} is bigger than \code{n}, the output #' will silently expand. #' @useDynLib plyr #' @keywords internal manip #' @export #' @examples #' split_indices(sample(10, 100, rep = TRUE)) #' split_indices(sample(10, 100, rep = TRUE), 10) split_indices <- function(group, n = 0L) { .Call(`_plyr_split_indices`, group, n) } plyr/R/strip-splits.r0000644000176200001440000000103512034020705014271 0ustar liggesusers#' 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/list-to-vector.r0000644000176200001440000000102612034020705014507 0ustar liggesusers#' 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/rename.r0000644000176200001440000000260212513035176013076 0ustar liggesusers#' 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}. #' @param warn_duplicated print a message if any name appears more #' than once in \code{x} after the operation. #' 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, warn_duplicated = TRUE ) { # This line does the real work of `rename()`. names(x) <- revalue(names(x), replace, warn_missing = warn_missing) # Check if any names are duplicated. duplicated_names <- names(x)[duplicated(names(x))] if (warn_duplicated && (length(duplicated_names) > 0L)) { duplicated_names_message <- paste0("`", duplicated_names, "`", collapse=", ") warning("The plyr::rename operation has created duplicates for the ", "following name(s): (", duplicated_names_message, ")", call. = FALSE) } x } plyr/R/quickdf.r0000644000176200001440000000133012034574010013243 0ustar liggesusers#' 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/id.r0000644000176200001440000000413512512025470012221 0ustar liggesusers#' 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) # nolint } 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) { x <- addNA(x, ifany = TRUE) id <- as.integer(x) 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/mutate.r0000644000176200001440000000265312512025470013127 0ustar liggesusers#' 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/indexed-array.r0000644000176200001440000000261312303221212014346 0ustar liggesusers#' 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") ) } #' @export length.indexed_array <- function(x) nrow(x$index) #' @export "[[.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) } #' @export names.indexed_array <- function(x) rownames(x$index) plyr/R/liply.r0000644000176200001440000000361612512025470012761 0ustar liggesusers#' 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. #' #' @section Warning:Deprecated, do not use in new code. #' @seealso \code{\link{plyr-deprecated}} #' @keywords manip #' @param .iterator iterator object #' @param .fun function to apply to each piece #' @param ... other arguments passed on to \code{.fun} #' @export # EXCLUDE COVERAGE START liply <- function(.iterator, .fun = NULL, ...) { .Deprecated("llply") 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. #' #' @section Warning:Deprecated, do not use in new code. #' @seealso \code{\link{plyr-deprecated}} #' @keywords internal #' @export isplit2 <- function (x, f, drop = FALSE, ...) { .Deprecated(c("splitter_d", "splitter_a")) 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")) } # EXCLUDE COVERAGE END plyr/R/l_ply.r0000644000176200001440000000335512725615763012767 0ustar liggesusers#' Split list, apply function, and discard results. #' #' For each element of a list, apply function and discard results #' #' @template ply #' @template l- #' @template -_ #' @export #' @examples #' l_ply(llply(mtcars, round), table, .print = TRUE) #' l_ply(baseball, function(x) print(summary(x))) 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.") pieces <- as.list(.data) n <- length(pieces) if (n == 0) return(invisible()) 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()) if (.parallel && .print) { message("Printing disabled for parallel processing") .print <- FALSE } 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(utils::capture.output(print(piece)), collapse = "\n") stop("with piece ", i, ": \n", piece, call. = FALSE) } } else { res <- .fun(piece, ...) } if (.print) { print(res) } progress$step() } if (.parallel) { setup_parallel() .paropts$.combine <- function(...) NULL i <- seq_len(n) fe_call <- as.call(c(list(quote(foreach::foreach), i = i), .paropts)) fe <- eval(fe_call) foreach::`%dopar%`(fe, do.ply(i)) } else { for (i in seq_len(n)) { do.ply(i) } } invisible() } plyr/R/take.r0000644000176200001440000000135312512025470012550 0ustar liggesusers#' 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 #' @keywords manip #' @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/adply.r0000644000176200001440000000172712512025470012742 0ustar liggesusers#' 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 #' @param .id name(s) of the index column(s). #' Pass \code{NULL} to avoid creation of the index column(s). #' Omit or pass \code{NA} to use the default names #' \code{"X1"}, \code{"X2"}, \ldots. #' Otherwise, this argument must have the same length as #' \code{.margins}. #' @export adply <- function(.data, .margins, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL, .id = NA) { pieces <- splitter_a(.data, .margins, .expand, .id) .id <- NA if (is.null(attr(pieces, "split_labels"))) { .id <- NULL } ldply(.data = pieces, .fun = .fun, ..., .progress = .progress, .inform = .inform, .parallel = .parallel, .paropts = .paropts, .id = .id) } plyr/R/count.r0000644000176200001440000000457212303221212012750 0ustar liggesusers#' 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.atomic(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/name-rows.r0000644000176200001440000000163412512025470013536 0ustar liggesusers#' 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 #' @keywords manip #' @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/r_ply.r0000644000176200001440000000203312303221212012733 0ustar liggesusers#' 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) { .rlply_worker(.n, .progress, eval.parent(substitute(function() .expr)), .discard = TRUE, .print = .print) invisible(NULL) } plyr/R/loop_apply.R0000644000176200001440000000056413573504410013751 0ustar liggesusers#' 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 #' @keywords internal manip loop_apply <- function(n, f, env = parent.frame()) { .Call(loop_apply_, as.integer(n), f, env) } plyr/R/round-any.r0000644000176200001440000000204112303221212013521 0ustar liggesusers#' 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") } #' @export round_any.numeric <- function(x, accuracy, f = round) { f(x / accuracy) * accuracy } #' @export 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/aaply.r0000644000176200001440000000310212512025470012724 0ustar liggesusers#' 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)}. #' #' @section Warning:Passing a data frame as first argument may lead to #' unexpected results, see \url{https://github.com/hadley/plyr/issues/212}. #' #' @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/mdply.r0000644000176200001440000000165112035653720012757 0ustar liggesusers#' 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/progress.r0000644000176200001440000001241112725617155013502 0ustar liggesusers#' 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) NULL, step = function() NULL, term = function() NULL ) } #' 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 <<- utils::txtProgressBar(max = x, style = style, ...) utils::setTxtProgressBar(txt, 0) }, step = function() { n <<- n + 1 utils::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(requireNamespace("tcltk", quietly = TRUE)) n <- 0 tk <- NULL list( init = function(x) { tk <<- tcltk::tkProgressBar(max = x, title = title, label = label, ...) tcltk::setTkProgressBar(tk, 0) }, step = function() { n <<- n + 1 tcltk::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 <<- utils::winProgressBar(max = x, title = title, ...) # nolint utils::setWinProgressBar(win, 0) # nolint }, step = function() { n <<- n + 1 utils::setWinProgressBar(win, n) # nolint }, term = function() close(win) ) } plyr/R/colwise.r0000644000176200001440000000506212303221212013260 0ustar liggesusers#' 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/m_ply.r0000644000176200001440000000133412035653700012746 0ustar liggesusers#' 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/arrange.r0000644000176200001440000000316212035565262013253 0ustar liggesusers#' 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/llply.r0000644000176200001440000000466012725615761013002 0ustar liggesusers#' 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(utils::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(quote(foreach::foreach), i = i), .paropts)) fe <- eval(fe_call) result <- foreach::`%dopar%`(fe, 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/maply.r0000644000176200001440000000157412035653710012757 0ustar liggesusers#' 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/each.r0000644000176200001440000000430712512025470012526 0ustar liggesusers#' 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) 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, ...) # nolint if (length(res) == 1) names(res) <- unames res } } else { # nolint start proto <- NULL result <- NULL # nolint end 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, ...) # nolint proto <<- list_to_vector(result) } else { for (i in 1:n) proto[[i]] <- fs[[i]](x, ...) # nolint } proto } } } plyr/R/a_ply.r0000644000176200001440000000111212512025772012726 0ustar liggesusers#' 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, .inform = .inform, .print = .print, .parallel = .parallel, .paropts = .paropts) } plyr/R/rdply.r0000644000176200001440000000311012511213671012750 0ustar liggesusers#' Replicate expression and return results in a data frame. #' #' Evaluate 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}} #' @param .id name of the index column. Pass \code{NULL} to avoid creation of #' the index column. For compatibility, omit this argument or pass \code{NA} #' to use \code{".n"} as column name. #' @return a data frame #' @export #' @references Hadley Wickham (2011). The Split-Apply-Combine Strategy for Data #' Analysis. Journal of Statistical Software, 40(1), 1-29. #' \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", .id = NA) { res <- .rlply_worker(.n, .progress, eval.parent(substitute(function() .expr))) names(res) <- seq_len(.n) if (is.null(.id)) { labels <- NULL } else { labels <- data.frame(.n = seq_len(.n)) if (!is.na(.id)) { names(labels) <- .id } } list_to_dataframe(res, labels) } plyr/R/here.r0000644000176200001440000000166312512025470012553 0ustar liggesusers#' 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)) # nolint fun <- eval(call, parent.frame()) attr(fun, "srcref") <- srcfilecopy("", deparse(call)) fun } plyr/R/ldply.r0000644000176200001440000000204412511213671012747 0ustar liggesusers#' 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 #' @param .id name of the index column (used if \code{.data} is a named list). #' Pass \code{NULL} to avoid creation of the index column. For compatibility, #' omit this argument or pass \code{NA} to avoid converting the index column #' to a factor; in this case, \code{".id"} is used as colum name. #' @export ldply <- function(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL, .id = NA) { if (!inherits(.data, "split")) .data <- as.list(.data) res <- llply(.data = .data, .fun = .fun, ..., .progress = .progress, .inform = .inform, .parallel = .parallel, .paropts = .paropts) if (identical(.id, NA)) { .id <- ".id" id_as_factor <- FALSE } else { id_as_factor <- TRUE } list_to_dataframe(res, attr(.data, "split_labels"), .id, id_as_factor) } plyr/R/splat.r0000644000176200001440000000131412034020705012737 0ustar liggesusers#' `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/NEWS.md0000644000176200001440000004266513627315342012361 0ustar liggesusers# plyr 1.8.6 * Update so `R CMD check` passes cleanly on R and R-devel. # plyr 1.8.5 * Update so `R CMD check` passes cleanly on R and R-devel. # Version 1.8.4 * Update so `R CMD check` passes cleanly on R and R-devel. # Version 1.8.3 * Revert to C version of `loop_apply()` as Rcpp version was appears to be having PROTECTion problems. (Also fixes #256) # Version 1.8.2 * Update for changes in R namespace best-practices. * New parameter `.id` to `adply()` that specifies the name(s) of the index column(s). (Thanks to Kirill Müller, #191) * Fix bug in `split_indices()` when `n` isn't supplied. * Fix bug in `.id` parameter to `ldply()` and `rdply()` allowing for `.id = NULL` to work as described in the help. (Thanks to Doug Mitarotonda, #207, and Marek, #224 and #225) * Deprecate exotic functions `liply()` and `isplit2()`, remove unused and unexported functions `dots()` and `parallel_fe()` (Thanks to Kirill Müller, #242, #248) * Warn on duplicate names that cause certain array functions to fail. (Thanks to Kirill Müller, #211) * Parameter `.inform` is now honored for `?_ply()` calls. (Thanks to Kirill Müller, #209) # Version 1.8.1 * New parameter `.id` to `ldply()` and `rdply()` that specifies the name of the index column. (Thanks to Kirill Müller, #107, #140, #142) * The .id column in `ldply()` is generated as a factor to preserve the sort order, but only if the new `.id` parameter is set. (Thanks to Kirill Müller, #137) * `rbind.fill` now silently drops NULL inputs (#138) * `rbind.fill` avoids array copying which had produced quadratic time complexity. `*dply` of large numbers of groups should be faster. (Contributed by Peter Meilstrup) * `rbind.fill` handles non-numeric matrix columns (i.e. factor arrays, character arrays, list arrays); also arrays with more than 2 dimensions can be used. Dimnames of array columns are now preserved. (Contributed by Peter Meilstrup) * `rbind.fill(x,y)` converts factor columns of Y to character when columns of X are character. `join(x,y)` and `match_df(x,y)` now work when the key column in X is character and Y is factor. (Contributed by Peter Meilstrup) * Fix faulty array allocation which caused problems when using `split_indices` with large (> 2^24) vectors. (Fixes #131) * `list_to_array()` incorrectly determined dimensions if column of labels contained any missing values (#169). * `r*ply` expression is evaluated exactly `.n` times, evaluation results are consistent with side effects. (#158, thanks to Kirill Müller) # Version 1.8 ## New features and functions * `**ply` gain a `.inform` argument (previously only available in `llply`) - this gives more useful debugging information at the cost of some speed. (Thanks to Brian Diggs, #57) * if `.dims = TRUE` `alply`'s output gains dimensions and dimnames, similar to `apply`. Sequential indexing of a list produced by `alply` should be unaffected. (Peter Meilstrup) * `colwise`, `numcolwise` and `catcolwise` now all accept additional arguments in .... (Thanks to Stavros Macrakis, #62) * `here` makes it possible to use `**ply` + a function that uses non-standard evaluation (e.g. `summarise`, `mutate`, `subset`, `arrange`) inside a function. (Thanks to Peter Meilstrup, #3) * `join_all` recursively joins a list of data frames. (Fixes #29) * `name_rows` provides a convenient way of saving and then restoring row names so that you can preserve them if you need to. (#61) * `progress_time` (used with `.progress = "time"`) estimates the amount of time remaining before the job is completed. (Thanks to Mike Lawrence, #78) * `summarise` now works iteratively so that later columns can refer to earlier. (Thanks to Jim Hester, #44) * `take` makes it easy to subset along an arbitrary dimension. * Improved documentation thanks to patches from Tim Bates. ## Parallel plyr * `**ply` gains a `.paropts` argument, a list of options that is passed onto `foreach` for controlling parallel computation. * `*_ply` now accepts `.parallel` argument to enable parallel processing. (Fixes #60) * Progress bars are disabled when using parallel plyr (Fixes #32) ## Performance improvements * `a*ply`: 25x speedup when indexing array objects, 3x speedup when indexing data frames. This should substantially reduce the overhead of using `a*ply` * `d*ply` subsetting has been considerably optimised: this will have a small impact unless you have a very large number of groups, in which case it will be considerably faster. * `idata.frame`: Subsetting immutable data frames with `[.idf` is now faster (Peter Meilstrup) * `quickdf` is around 20% faster * `split_indices`, which powers much internal splitting code (like `vaggregate`, `join` and `d*ply`) is about 2x faster. It was already incredibly fast ~0.2s for 1,000,000 obs, so this won't have much impact on overall performance ## Bug fixes * `*aply` functions now bind list mode results into a list-array (Peter Meilstrup) * `*aply` now accepts 0-dimension arrays as inputs. (#88) * `count` now works correctly for factor and Date inputs. (Fixes #130) * `*dply` now deals better with matrix results, converting them to data frames, rather than vectors. (Fixes #12) * `d*ply` will now preserve factor levels input if `drop = FALSE` (#81) * `join` works correctly when there are no common rows (Fixes #74), or when one input has no rows (Fixes #48). It also consistently orders the columns: common columns, then x cols, then y cols (Fixes #40). * `quickdf` correctly handles NA variable names. (Fixes #66. Thanks to Scott Kostyshak) * `rbind.fill` and `rbind.fill.matrix` work consistently with matrices and data frames with zero rows. Fixes #79. (Peter Meilstrup) * `rbind.fill` now stops if inputs are not data frames. (Fixes #51) * `rbind.fill` now works consistently with 0 column data frames * `round_any` now works with `POSIXct` objects, thanks to Jean-Olivier Irisson (#76) # Version 1.7.1 * Fix bug in id, using numeric instead of integer # Version 1.7 * `rbind.fill`: if a column contains both factors and characters (in different inputs), the resulting column will be coerced to character * When there are more than 2^31 distinct combinations `id`, switches to a slower fallback strategy using strings (inspired by `merge`) that guarantees correct results. This fixes problems with `join` when joining across many columns. (Fixes #63) * `split_indices` checks input more aggressively to prevent segfaults. Fixes #43. * fix small bug in `loop_apply` which lead to segfaults in certain circumstances. (Thanks to Pål Westermark for patch) * `itertools` and `iterators` moved to suggests from imports so that plyr now only depends on base R. # Version 1.6 * documentation improved using new features of `roxygen2` * fixed namespacing issue which lead to lost labels when subsetting the results of `*lply` * `colwise` automatically strips off split variables. * `rlply` now correctly deals with `rlply(4, NULL)` (thanks to bug report from Eric Goldlust) * `rbind.fill` tries harder to keep attributes, retaining the attributes from the first occurrence of each column it finds. It also now works with variables of class `POSIXlt` and preserves the ordered status of factors. * `arrange` now works with one column data frames # Version 1.5.2 * `d*ply` returns correct number of rows when function returns vector * fix NAMESPACE bug which was causing problems with ggplot2 # Version 1.5.1 * `rbind.fill` now treats 1d arrays in the same way as `rbind` (i.e. it turns them into ordinary vectors) * fix bug in rename when renaming multiple columns # Version 1.5 (2011-03-02) ## New features * new `strip_splits` function removes splitting variables from the data frames returned by `ddply`. * `rename` moved in from reshape, and rewritten. * new `match_df` function makes it easy to subset a data frame to only contain values matching another data frame. Inspired by http://stackoverflow.com/questions/4693849. ## Bug fixes * `**ply` now works when passed a list of functions * `*dply` now correctly names output even when some output combinations are missing (NULL) (Thanks to bug report from Karl Ove Hufthammer) * `*dply` preserves the class of many more object types. * `a*ply` now correctly works with zero length margins, operating on the entire object (Thanks to bug report from Stavros Macrakis) * `join` now implements joins in a more SQL like way, returning all possible matches, not just the first one. It is still a (little) faster than merge. The previous behaviour is accessible with `match = "first"`. * `join` is now more symmetric so that `join(x, y, "left")` is closer to `join(y, x, "right")`, modulo column ordering * `named.quoted` failed when quoted expressions were longer than 50 characters. (Thanks to bug report from Eric Goldlust) * `rbind.fill` now correctly maintains POSIXct tzone attributes and preserves missing factor levels * `split_labels` correctly preserves empty factor levels, which means that `drop = FALSE` should work in more places. Use `base::droplevels` to remove levels that don't occur in the data, and `drop = T` to remove combinations of levels that don't occur. * `vaggregate` now passes `...` to the aggregation function when working out the output type (thanks to bug report by Pavan Racherla) # Version 1.4.1 (2011-04-05) * Add citation to JSS article # Version 1.4 (2011-01-03) * `count` now takes an additional parameter `wt_var` which allows you to compute weighted sums. This is as fast, or faster than, `tapply` or `xtabs`. * Really fix bug in `names.quoted` * `.` now captures the environment in which it was evaluated. This should fix an esoteric class of bugs which no-one probably ever encountered, but will form the basis for an improved version of `ggplot2::aes`. # Version 1.3.1 (2010-12-30) * Fix bug in `names.quoted` that interfered with ggplot2 # Version 1.3 (2010-12-28) ## New features * new function `mutate` that works like transform to add new columns or overwrite existing columns, but computes new columns iteratively so later transformations can use columns created by earlier transformations. (It's also about 10x faster) (Fixes #21) ## Bug fixes * split column names are no longer coerced to valid R names. * `quickdf` now adds names if missing * `summarise` preserves variable names if explicit names not provided (Fixes #17) * `arrays` with names should be sorted correctly once again (also fixed a bug in the test case that prevented me from catching this automatically) * `m_ply` no longer possesses .parallel argument (mistakenly added) * `ldply` (and hence `adply` and `ddply`) now correctly passes on .parallel argument (Fixes #16) * `id` uses a better strategy for converting to integers, making it possible to use for cases with larger potential numbers of combinations # Version 1.2.1 (2010-09-10) * Fix bug in llply fast path that causes problems with ggplot2. # Version 1.2 (2010-09-09) ## New features * `l*ply`, `d*ply`, `a*ply` and `m*ply` all gain a .parallel argument that when `TRUE`, applies functions in parallel using a parallel backend registered with the foreach package: ```R 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 doParallel::registerDoParallel(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). # Version 0.2 ## 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 of rbind.fill that copies attributes. # Version 0.1.6 (2009-04-15) ## Improvements: * all ply functions deal more elegantly when given function names: can supply a vector of function names, and name is used as label in output * failwith and each now work with function names as well as functions (i.e. "nrow" instead of nrow) * each now accepts a list of functions or a vector of function names * l*ply will use list names where present * if .inform is TRUE, error messages will give you information about where errors within your data - hopefully this will make problems easier to track down * d*ply no longer converts splitting variables to factors when drop = T (thanks to bug report from Charlotte Wickham) ## Speed-ups * massive speed ups for splitting large arrays * fixed typo that was causing a 50% speed penalty for d*ply * rewritten rbind.fill is considerably (> 4x) faster for many data frames * colwise about twice as fast ## Bug fixes: * daply: now works when the data frame is split by multiple variables * aaply: now works with vectors * ddply: first variable now varies slowest as you'd expect # Version 0.1.5 (2009-02-23) * colwise now accepts a quoted list as its second argument. This allows you to specify the names of columns to work on: colwise(mean, .(lat, long)) * d_ply and a_ply now correctly pass ... to the function # Version 0.1.4 (2008-12-12) * Greatly improved speed (> 10x faster) and memory usage (50%) for splitting data frames with many combinations * Splitting variables containing missing values now handled consistently # Version 0.1.3 (2008-11-19) * Fixed problem where when splitting by a variable that contained missing values, missing combinations would be drop, and labels wouldn't match up # Version 0.1.2 (2008-11-18) * `a*ply` now works correctly with array-lists * drop. -> .drop * `r*ply` now works with ... * use inherits instead of is so method package doesn't need to be loaded * fix bug with using formulas # Version 0.1.1 (2008-10-08) * argument names now start with . (instead of ending with it) - this should prevent name clashes with arguments of the called function * return informative error if .fun is not a function * use full names in all internal calls to avoid argument name clashes plyr/MD50000644000176200001440000002415613627466102011567 0ustar liggesusers415c12c2c2d182bb9a9346ec30f3229a *DESCRIPTION 7bb6b2019939096672a443d7b6e80d5b *LICENSE 5c0d46d0e919fbbec9f37864fee394f2 *NAMESPACE af1184c149876d394751c33b83abb19d *NEWS.md abdba3958a1bc9467ac29e00163cc64c *R/RcppExports.R 2cacb3ab0a140e444938f826a09b7a0d *R/a_ply.r 4b2f1db5592db1334de9bd61ee98436b *R/aaply.r f2604fbe88644ec6f399539b4f5dbff0 *R/adply.r effba88914db9ef403f64b4b0d00a8d5 *R/alply.r 27850e8a34d803a77059aee92fe98a51 *R/arrange.r 6eddac05a5943b98bcd29462cddc5390 *R/colwise.r a3b498c0d8ed5f7e1a390f9efbbef4f4 *R/count.r 6b68e71c118e44176bc1208233cb7137 *R/d_ply.r 0ad7db00b35f5faee233ce24b748a8a1 *R/daply.r 50cff93340befcbf6deb04405ead23b2 *R/data-frame.r 526de3e3bf03679c79a9b4165d6cc128 *R/data.r 321bf16b07873b178be8484f5469af72 *R/ddply.r 201c9ac2be5dfa8fa52575e9b459bb64 *R/defaults.r abdf36c15fa6440db800895aa3695571 *R/dimensions.r a7343f7e3aad4a4a11879dd842576c29 *R/dlply.r 73c12c892419c28e8b78bf73dfccfc63 *R/each.r 0fd02775e3776a16238525b97b99881d *R/here.r 13cbaf54ee3454297e2b2712530e00f3 *R/id.r d11be448754a6f5b24301dfadefd3f05 *R/idataframe.r fc14994abc7f86af89a188295a2dc5f5 *R/indexed-array.r 229267201ee89bc089a3b3f7c6fba5cb *R/indexed-data-frame.r 4e3adb71aeb565d48c87cb1592b13714 *R/indexed.r cd70a68dd7556c7b463c64fbb0de98f2 *R/join-all.r bd3b37f2d0c588b577729987a7b390b2 *R/join.r fbad4b6c69bc03fe649a893c6ee41061 *R/l_ply.r 49db6bd50575429654a36aec5fca75dc *R/laply.r 5c0761febd091075fd2c3c375458b9de *R/ldply.r 996456dbd8d9748c3d7273a0b66b3cc0 *R/liply.r b082625367148bbede12cdeae2d9676d *R/list-to-array.r d2d461c086c0a59c3e8bcdc2f5760086 *R/list-to-dataframe.r 0235ddca614287ca137a2a5ec80b6ecc *R/list-to-vector.r 5b11e23dbf190ed0cdfae2c6377ad257 *R/llply.r 4cd1c4081262f0c3403ba58275f9016b *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 9340cf2fdf5f6be08886aac2037a7274 *R/mutate.r f883208d0ce69464dfbe690812161a44 *R/name-rows.r 45c5b329e5a1ab0aac2a6ccec2c2e60d *R/parallel.r f66e62cbef6484534c99dc3934eba248 *R/plyr-deprecated.r b16022bfa5bd8b41a0b6cf68546269a9 *R/plyr.r 22232615909daf78127cfde12d5e199d *R/progress-time.r 77e7c5e10eb6de675e000b27e006c805 *R/progress.r 87b4723fec09c203ea9c98373d87cb4b *R/quickdf.r 4505d22d30f983ade43482967a8873d3 *R/quote.r d2d78e4a2a595733f0f9b15b50a36ce0 *R/r_ply.r 9280ab29ec7162e29f330717de5ee90e *R/raply.r 7194e3bd1fbe13a89129d3b9533f664a *R/rbind-fill-matrix.r 1172e74c2413042240b54e53cc239d5c *R/rbind-fill.r 514f68d869a789c77abde662808b7649 *R/rdply.r 415e517a3aa9f222679efad6c5729a3c *R/rename.r ddd658679cca81363137627bfe7edaa2 *R/revalue.r a174b1efb8b3bec8dbf7256d12dad2fa *R/rlply.r b0d8beec3c1c5cab302e9454c8b16d33 *R/round-any.r 7369a7d69027736f1e62f0f49fa8aed6 *R/splat.r 29e4abb6bc1f7561ff08c08554ccb58c *R/split.r 3a1bdc96de5cdbeb96ece99f27d2567f *R/splitter-a.r 75bdf5f45ad79a232c5da028f3206489 *R/splitter-d.r c3f4bc5baaa2be00a96fae50f235097a *R/strip-splits.r 9df07a1821d3b3c8698b387f037156d4 *R/summarise.r def748e3cbe191df41ddbf5804d48bd2 *R/take.r 74343cc970ed6691fa2d2a0b18c3a7c5 *R/try.r 40779d49b8ac7f779f3201fb22c5bb6b *R/utils.r 3114568678a3ce43b5347986cb14597b *R/vaggregate.r 3a9addae7789bf3927559de0ca8d27b3 *README.md 9b2d63a08f6c4d1718642d2c904c230a *data/baseball.rda 12d6f72bbc8c97a10e7c4c235aab3ae3 *data/ozone.rda c064ec8464bce62b7862acec50e8475b *inst/CITATION 93bc5f6e45ccf974d831a60ae44b54d0 *man/a_ply.Rd 74d4f1202be67a99b46ad16f79fb7553 *man/aaply.Rd 2e6868119bc537557fa30d7c842f2ef4 *man/adply.Rd b8020370b47256e981bd330baa196f05 *man/alply.Rd 0a93eecc9471df20ac9dcb859d92fdae *man/amv_dim.Rd 7d3c87a1f2197718de807441115fae2d *man/amv_dimnames.Rd 45af57704367812d9fbcc165a00b7741 *man/arrange.Rd 80337482edcb02f34eb28b83112dc167 *man/as.data.frame.function.Rd 93de026bd5498c259135fb0e7775c679 *man/as.list.split.Rd 39aa247e4e9b789e69c80c5951e021d9 *man/as.quoted.Rd e95045369653360e99bdc6e04ea16fb5 *man/baseball.Rd de49d7be4c7ce4259d54591da8fea518 *man/colwise.Rd a6f87ceb4c44ea8162eb87fa83484271 *man/compact.Rd a0b3db9010a18e7c87bc2080979931c7 *man/count.Rd fa403b474c711fe328dafb3d9cd10bdf *man/create_progress_bar.Rd d05342998ab2ed0ea5d02830f204dabe *man/d_ply.Rd 06efc5bb52e9ed15cc910b39a7c30e6c *man/daply.Rd d694cf0643fd271a0959984ed93f4bff *man/ddply.Rd 197731bb7ba97db2d8588a4c2f8f77ff *man/defaults.Rd e1a4786b8ffee7ddc4992515bbe080eb *man/desc.Rd 3faa682fe224adbb8346a3eb0701476a *man/dims.Rd 0aceada4bc45a6a912556cf113947387 *man/dlply.Rd 92404345cbb7e634eb440fdfe43dd372 *man/each.Rd 1334bee63a5ad1215b9e86c0af2618bc *man/empty.Rd 6a222f63f70d77f8579b2e088d849a98 *man/eval.quoted.Rd 3ce92951bae0e38e50b877d1743985a0 *man/failwith.Rd 0393f875f6460944222fefd77c8a9e0a *man/get-split.Rd b6c5b9b303ae515602c3de6f0d1e8e9b *man/here.Rd 21483c61fc502be5478b37e76685564e *man/id.Rd 2933128974f6400a0830d3f850e20494 *man/id_var.Rd 2a0a8f30e5708d74f712427342666b9d *man/idata.frame.Rd 444a2e3d31e087d531292d6d390eacae *man/indexed_array.Rd d4ab07cfea28ffe36f4f716f793d6861 *man/indexed_df.Rd a7701e8ca05b4696e362e1f1ca7922c8 *man/is.discrete.Rd 551b4c8a249b471079a231a294f7af1a *man/is.formula.Rd e5ec664f096e2e36d08565793b75a57e *man/isplit2.Rd 631545f284bca54db8c68f2c39d1e602 *man/join.Rd be6ba4498650ee420e594db610a9737a *man/join.keys.Rd 4e334f4ff139833dbdd15f72a766105d *man/join_all.Rd 3fc6179b7f05c02c7ac58d5719917d2b *man/l_ply.Rd 4c29f256b5523e327fe2ad7a21a06ec4 *man/laply.Rd 96937ad590aaf25396e1e3f7a08d25e5 *man/ldply.Rd 491e4d3f4b17ea1ec2872d1c20b0dfa9 *man/liply.Rd aa445615c2beab61209558e5a10fcf76 *man/list_to_array.Rd 5cb59897f9e95bacbf51eabca4929559 *man/list_to_dataframe.Rd 2a67df4e70941cf54738c51b756328d3 *man/list_to_vector.Rd 9fc90974ff8db2d61661c891ce9eadd4 *man/llply.Rd 6875b063c8095d67b5d54e352a6f87cc *man/loop_apply.Rd 58f22d3008ceff3601305afb6ca01bd7 *man/m_ply.Rd 86f06288995a6421ed2d6ddfae60fccb *man/maply.Rd fcf8541b3f5064479f4c6d07c00b2bfb *man/mapvalues.Rd 7fb3507682404a94c8eb09cdf8e14792 *man/match_df.Rd f223a0a97b414e3868712c6e54c4ffaa *man/mdply.Rd 648f1199cc36608f8ebd5a36c308e150 *man/mlply.Rd 22ed584b87c63d30427f181b41c761ed *man/mutate.Rd d5c30879f88548dbd5b50d8becc17fdd *man/name_rows.Rd 7866f5990d7e17b52b60a9656c8e19fb *man/names.quoted.Rd ae1db878bcbbbe58951ad88ab5bce2cf *man/nunique.Rd 36923f93a08048438f4007f418a7e8b2 *man/ozone.Rd 3e6ecf4729db59d99039d59562ab5d3d *man/plyr-deprecated.Rd 5ed6057b4d9fc9c91e7053926472b7eb *man/plyr.Rd 5d7aa6a9d85c89865c78efd18330f3b8 *man/print.quoted.Rd 6c79c845ab406a6758785b0e5838fd1e *man/print.split.Rd f43a15d3287d228b61465d04703ed815 *man/progress_none.Rd ad99862c150ba61755960e9c3bf8a6a6 *man/progress_text.Rd 185aff856057a61b8647133afdd9ffa8 *man/progress_time.Rd e32c6002744965dd978ee45f7d0cf627 *man/progress_tk.Rd e4aa1e7f953049a9f1ccdd161d4509da *man/progress_win.Rd e175951b3453a45dfc6bd1d5ddeeb83b *man/quickdf.Rd 91b702f1c9c3cde42362c7361db1efce *man/quoted.Rd fc27cefdb50fba2ce8795588b15fedca *man/r_ply.Rd 39be1e79c77d1328a59e748f4fc26cc3 *man/raply.Rd bf7defa9e764961b27464998027684c7 *man/rbind.fill.Rd ec767ee7c7e2b3704ab81f09688c6c8f *man/rbind.fill.matrix.Rd a010b6dc8ff3e401b8e4a27fc3da02f0 *man/rdply.Rd ad121f0453f32d07151fc2f6bc09fae8 *man/reduce_dim.Rd 097e33c6039cbc3539ada6acf5debb58 *man/rename.Rd 4c43785804a454b7e40b4a624b28bd9a *man/revalue.Rd 01471329764b3e1b9e69ecd29aa92be0 *man/rlply.Rd be39e715e7b9c8835e34b50bf60d5205 *man/round_any.Rd 7c7a763aef9ccc9d7f28e090a05a7370 *man/splat.Rd ccc2a8792c5fb682bf3b5c03689169f9 *man/split_indices.Rd 1cd17fb70d34a834d32df7a2c863bdbe *man/split_labels.Rd 175a3eaede061236f55df8d299ae60c8 *man/splitter_a.Rd 9ddc1bfd57d89ee6ba2f69b52e17f0c4 *man/splitter_d.Rd b0d92e136a4c798d785ae187ad4d951f *man/strip_splits.Rd 501671f0bcc651348dfbd93dc354f71c *man/summarise.Rd fa864cc22e387aabd47320e0999971aa *man/take.Rd 0eafb1253a048db37acd074c14d09669 *man/true.Rd fa671011ac999b9b9c0c8e830cacfa00 *man/try_default.Rd 4ca79656e7c95f60290a714a99f98681 *man/tryapply.Rd 357294265377c152c454f2c77ec432f2 *man/unrowname.Rd be479917e2a9f5881bbab74e5ee01e60 *man/vaggregate.Rd 6c35ed3a864ac077dccd1712be919693 *src/RcppExports.cpp 75d31e4f078aa79bd86e91ee5f85b322 *src/loop_apply.c 635efc489b194a6b73c08a2e2896b36f *src/split-numeric.cpp 3c5e14d243849a45ef414e14aa5a5184 *tests/testthat.R d564b7820ed6c9598ef0e9f39913a4dc *tests/testthat/quickdf.r 276325b0874ec8b9dae723d82a2be520 *tests/testthat/test-arrange.r 09334c7a36081c3009350191e56f3271 *tests/testthat/test-array.r 585d837144509f399649df533db01824 *tests/testthat/test-count.r 8e4432b2f786df04c93acbc3df0e6dd8 *tests/testthat/test-data-frame.r e48e8b4ea198110449eee62660bb7f87 *tests/testthat/test-debug.r 570589b2d8f6a5e7a5a9292bde0255c3 *tests/testthat/test-empty.r ba14e87b8bb1b0bde96358cab3800140 *tests/testthat/test-id.r 22fb32944156a59fb79d4b9b9185f685 *tests/testthat/test-idf.r 8bc102a986a50c553fa40ad13edc7f39 *tests/testthat/test-inform.r ca184609d73e0d3d4a605e1da787716f *tests/testthat/test-join.r d09ac8d7646b3d6c434c50467580dc8c *tests/testthat/test-list.r 9f2f96ae51cb9f43ba79bbff45c9f767 *tests/testthat/test-manip.r e4a2dbcd3e829d98895ac697916dbfc5 *tests/testthat/test-mapply.r 0d1b884651b4e602c267673c4f86c130 *tests/testthat/test-mutate.r c66dedf6251001e69782f7c3f5a54349 *tests/testthat/test-ninteraction.r a862ac5d7ab225e96258d6d67d820239 *tests/testthat/test-parallel.r 146c98c42bcdd398d2805c35aaf83b6d *tests/testthat/test-progress.r 173260708c547a2ebd96c2cd797c8e07 *tests/testthat/test-quote.r d40b96dc9207f3ce52b59c2b41044b26 *tests/testthat/test-rbind.matrix.r a553970d65b2e74e6d73c230c6e2ae6f *tests/testthat/test-rbind.r 567571b52e4ddee6873533f2f1ed3185 *tests/testthat/test-rename.r 30bab23a097dc350296100a63088b04e *tests/testthat/test-replicate.r a4727a9d37fcf4385aab5b72866d8332 *tests/testthat/test-revalue.r 949976e498103b10ace8b99e01d8c38a *tests/testthat/test-rply.r c2a2f2887e3926a850e1923ae62689a0 *tests/testthat/test-simplify-df.r 8333352212f7d58b1e53ce26a60afb5f *tests/testthat/test-split-data-frame.r d2dd8597307e5cd0b7bb7e1bae4ab331 *tests/testthat/test-split-indices.r 3f495423863339ea9467c8c1ca40c7c7 *tests/testthat/test-split-labels.r 2ccbc25d64e4f30451be4b5c019c7071 *tests/testthat/test-summarise.r b76073a4e32c45b1bc2cbd8911329cc7 *tests/testthat/test-utils.r plyr/inst/0000755000176200001440000000000013627315360012223 5ustar liggesusersplyr/inst/CITATION0000644000176200001440000000117012034020705013342 0ustar liggesuserscitHeader("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/.") )