maptree/0000755000176000001440000000000012054614656011750 5ustar ripleyusersmaptree/data/0000755000176000001440000000000012052524053012646 5ustar ripleyusersmaptree/data/oregon.border.tab.gz0000644000176000001440000001003512052524053016521 0ustar ripleyuserseY-nDs{o>=Ǟ׊>tbW$oi_9of/#@WZ_eo;_/[Sr;+nxoZ3fw^Zn+Md*,癯KiSd2;X޵=Ix|&qYSwߪU9q k\N-HkVG?}!8}i{~w<~ySG=xYK[ G<^-ĉ˓=Q=!笵AZ,ZF;sSҗ"r 9軕!>gpW8sDښ<9eslpM8vGRrnd Bgs_'Y.Ād#Kg\f4иbZ;OR#*W\Xc[/Du+8jYM`U%W[ke ~06 [*`T +jT>mv `RrMUG{ jN´پeJz}F͔w-&@<%Bа`Q-sAa&dh{kT)f=sK`1i?V/`lsu~7S_5ݼ9y6 d pnf^iW!Dr嚓pPsTtM0/EY4/ 9Ә58kwme+6`P*+Bl#vx5pt"(/S1z,a=^S :w-d@ Pj%"v; 3l1YtLTSAR5sLbXST!o'o G{3jqAG] LQĭ41&^؅@McY:ףT-Ļ\KaܘE$ #4c.1@OIFy8X P&eHXI+b{FìDHz8.2f|qϰwzsX?#@.<2,dm ꬏ ,61:>+1'J=7~ffjf*YS<23#r!3TNSbb1<_ EWHA٢mmjy @v-\WtP5z#=i=^7Of=N$bB{DGC ЄL29>ҏT?r/Ffh*aD^DbzZB(@_-wL-U'm@GE֓ZhՓ<_Jgr2F rc2u5#%`.4cs9z dyJakGW5>)ڙuHZ=`2GtSI 5}B$OO%[SfI܏j3Lޫed4B#Ay_xC<$RJ&IFecXg"~pxS2LHҎez[^4 }jEЁd_*nFIFgҶW}y)XCQ<׏y22M3&N d@MtCդ'Gs4B by_VPK9M:уiӈGPFƚcK*8(k!^Ǵ֛DюP;QCz^uCN@vT$-9r"{JT`:&M\ |j33- Ny9uuh| NF.1rXDfH"Y#/@`0]"4y7b%@4q)G;(H©n3@V<bxֈ\K CQWфJL99=X8ҝUtCdDX(OF X:F\X_zhm^NWa'C}lQ=Ov\~eSBH'EeĢ0PS>{dw 9SN7 L=3mLKJ4|unQXna] ^&ҋu(q*)Io\5ŏoC=]~@<6r*oi38Ͽ{DV3썼PADV>I1U^q|ChƊ7;y(p<53GG3'2ne,kj3mJkA\U_ V3:9'+ߞL#5-AyX'g|$ s 4qގ@́N؝yiR~"ԜBiûlçe<|^!lΟOy `>kd2<Dv._4y_RrZiG۟^EkyeMx&n^Zg)b!o}?s~߂}ۂ~ ve>xxچUǶGy  K!Çe}>o×m1\_?D}>.އey2|\|$t>ܯOc?5,ox /5~8f_>,6\ky>ߥ߇p6|Z5a>ox1\n _֣a;n6ކeYexZV l˖ۯR?[ߛ:oS؆cSX e>o×m[cMxZ'8%K8O۲u6<|ކK8ׇ6ues<\-Ǐ-[?:asq;9e[eYMx=}ڱ~oGWIކa>ns O 0޾\#ǶWۼ嵝Ǔyy'ٶ}"* ] ꯤlo*nmnOVV;:+auO^c,{RwcD^W5vL~I|'uFGܟ:ZԕzuoRq1^k귙zYwn:uVzMϵ[n:Ss/WM۩6JU:V澩SkgٖRy[ךŲQԵX3RX1tmphs"ʢ26OFݨ0SE6E#gkTNzG+'HzQQrJpnzL/{] ϧչEYJ]:)_9yţkۇ˫mH8s$Y"uE׷l*3uݗ~A}2VHR^.w_[n~w_PQ>\S>}P|{=um)G}~>4um?u/Cڍt_<TnNzPǚ.ΙPg J8r椢cO:«|m."ua(SS׍/Ex3{n}~tX}fdB]j^ǕIۣl*3F죮ջukjU[*u[R]3zS"S5)ekU>˽:׹RکN%yQWԽj1ڨG]פJ\z;xQPUAO-YWz;eݱקnx:+j xk~>6_xG04u(&UVgsꁞ\f GV L顫ģ~=^gccYǠ~LSSZ~eۺ4>EEQM~3uڜy$u*z^_k%yGٗkG{qU|q{{,R^OqB]ta:W7D f3J:2SuӝʗTF֚Ѯ3uy:G:gv|rSWʨ#RԹRou s9u{JR1umWH:#[U<Է*gOxJyo^G^왩R?ԏxWE uQOڟ]d u/Q]YzZS uS*ҽz]޷׭߅z_|ک<ݩ <꾝Z='GZ;3qwUzJg?긲uuO?`LHu޻zG5eG{W:u8 ֏\|'|RVVSWʷSgnkAz$Q3}RxL6s;zzuXL֋_ 9׏HsUgP OnzG3QgE~xՏR>knmPgRqMzP?w:GYG=Y rLimax+ eUԱ:WvꁞOm6WO+zAiliL'7MIOfE=u͝s?3Vʛ9k߲aUd3SGM}!>_tg,tU'+꾝9uiL'7f~ +f9QOFR/Խ^C]g>ڗک[ qwUkSOӝڣO]C}~1VP_.M=sΙje\O:L3{iTm'g^=u 6;^T:*y%0E|kZR, ɬ\t}kꪒ8ZKJ>SJ]:vq" ڨk.9\->uK* f'Kӽ:`'OOI<6Jg``]ePNJC^Y2x(xruw^uޙJXH]Gڃݠu$zQG{Qyī4$uXG1@mF `8o݇j%|cpXA^+fu;:SS kEP^!uo(ΙLV87E]1۩{]O]N^l?X#)RUPi^G3NScE0Sge|ꚳ`v6Ǡ9# @Ui\t}kʒn򜩏u]I=ȧάGPcQW\Ps#1SO5QR1ǚ^W^ϑUSd+Χ`h\VwUQkL=M?q~^Թs7GQǬxGl3.bs]3}>1+O%O ^W{_J^NwKQW>}>əPGAS9:!*TP=?uEċcL=oh7*omߡEhum3G]e֏z0+zRuyԃʷz=ˮ͕RfTB㮧HqD9qxꙩF|~b:ԊJf:d Xevc-uFO.Kb|ڨ{X}QUh'4uaUJ[oX㘩p7uͰ:ԙV u~aPGάs^o ~ܫ=4<\-!b\A.R-y__GsҾ^uͪ&E:f9:o\z=DԽz)U uάҮ:*l|O֋ы[Q76fmRԱsgu2b{3+h؅9Mv+%?M/-ɬ4UyA?,&Fi_Op\GUF%Y}DhQgZq2fLo2۹QR궯kzeMQ+-Qud-u늩sܥkuUǬzLڿɼzp*u[=ev#nnIPAhngSGZeѺ>feWd[c `E^IS+꨿GK+c(&Ճ:*n-92zFn{AO:f\N=Du2~FSg {9u)O}2Ѡ6J:1cvI9뙙Vud{sFRԕ9:h٧i4L}߂ C]:VuU18RTmpG +G_{MfYFѽJE])mƶ5ue3G.+)Vκ)LIYJSgE}c:Ʀ{3<ښ᝺w$)uTo=csxn u]ys1j%4ucenI]>)[9S5P2]Թ7ԃnCիj"Byjolyڳ*vRܹ"9W*٫e[؃{뼪׭*iҗΞ5uθ>ԕK劬O=A}V:甪feBk#Kݯhuh%Sy/K]鲗Λ_o-QיjyѿfuQg0{KVrY)%`}dzkS4.uW-IJTI?RPD~8g g[bV:muԙGVWPlqwKZKO`jo\ԋz=Ą/@]+Jbnq{fc^7G]UnRl};uT:h뼄zͻ/X{v\QWSWʖSGumFݗ6soiP۠>?f}kQurHCFQ罹zvfu}fQQ7ܯCgq]:Sgu|VV@Ҡ/u>]YG/,涱SqF uv_ꊑOVgE=HOUӵ`ٵUWjE۩c+%JSޛzKR>@3r\wxMȾYuV7wF#E3u3&V;fgL^3*06XRТFlɨ*MrrT%s(D0SuKfTBj/A=SWc.s;|y/G<uLݗrבbUN46E]QRLjʨKP/yeo5uQC KC%,w_Rԕ_:-PC,oݗ`VSWy }/Ƴy=;eUBu]VQ^xʨRvfc}XV)v{sV:꜏v)u~}:zꖶxmjO-{;Z=UK*7l🧾Gc+=%8:SmUבzY{&2ϥ9uuuTzL}ҔQG5Zꓘu}}>$ǧRye)6 9FԹB&iu_y^yUqGzvVԱ[Ҿͮz9s͍]:+SIZ6M]RϽZBu;8~ZQW#zO|4t;u3䌙%;:wwi\mL{ؓO: W%ZFݯ΅+Dz2LQGeu9zXz*F/b5q@eSyVIOdѧ^y㵊3_ Xke[׺^>uE1MDLtǭri,K>sU_C]lTO[%g';z|mQu Ys,-( _C"Zc#:zPǯ yiyE]S Cuj(h1M=%XBnIxW;jvŕo=Wk}bcVk6Ei*6;۲>bq u57u^.C+n+գuU=Ǩ^b6=1׽QcFԭE" uי7czQzu5/G]?>uki@]1e_/>yG2Qh6#P}l6V3{]3Fj4G`VL]3 4S_GM[#>wy uVuSg 9꾮i%XAlΞJI]KSm^ QZa꺮Kk>umO .W1.zmi'’3+SYʋvr,[*J٦λG'nvnYquG^Ms̕uɫgyƅ$VЧ*qWZWlV^G.VFk; wPj?z=vpsK3'q?u^Pz~?PRGԙ-&}O3uU{ݫ1YTKng铩Jz/mt66z{iR:2o{iC3>}X X^G|V7uPO+Uoʜqn펠חSY91[˨ۢV{ISs,u짮*6uTZyVQg{Rʩ8gOQ9'sjMSG%qșIu؆wR:۩ΫL/=VC=zQW+8Z UQks6VZՆ"\O=늺O5:^Sԭۥ>uȳکkum%ԅ3̵rgk{̙jo_"wd ,]|lgNw4SO_~6ڨ띨zR1RGы昣3}TN=h37kki]u&澩N} 7Zl:$ӵoU$A9zkԃ9:j{N@_龹:LPO7w[YKFyH}9E}:fJc3˩OƒUks:y6gh֩[^rm~ԑW:nGd6FPF\G9_ 1(^˩[-U}c~zɵr?y3S1 RWt۩XꜯU?czݏnν2uVTy `7:<բQe3$fk?D;sP~0_bz^ǙץS pCQ\W1,J }z掣αR6v{MG=Y[ :z1##{Y1:S+^=On|dԭ.cCFOOz^׽n :gnI>}>O'2usP4uC&+q l֣' N=Waz\ѧٝZ-u`uثs^G=קE{-ļA}~Pzyy=KX ԕ.S#ۣUs~5KkX>Q6k:j_Bԃw [D:+=ɹ%SzRP{/1zf rvuFhq|S]y9.OyZf (7kV[b^w v>>gs|c~Y+GPݜO5-6S[ uZ#>=R絥\o9R9u,{Bg1\ґzX3:ԃ{Է,uVz2s}bFRgU=;xPgzQsDݮC=Nk?Hx'9ek:{M'MP73{nuԃ[c.⬧LY{S'DSsX֊^f%FTVu$KP^//ngRw q娫J8;]U?G-u|\m$6Y?RJ}~31ռROCmQr}9qFMuk᭎]IDXeuãܬ&\SH<[+eԑ#9#^ \&uﮊ6V>~)걂)|VwWEuyz] P9Ovmaptree/data/oregon.env.vars.tab.gz0000644000176000001440000002100612052524053017006 0ustar ripleyusersUk$qkL>#B y/},̜*2?^z?^^~o~ooj=Nyq^׻WWkkyvԮV,S_uɜƫޭZ&~ϔ%4j}:VC|fW%e7K[ueQVʴWkHx:e="ҳL_J~fZC"K""'V=%tmu*Toc!Ξ3B~t~i9Ѫ~j_:Z>=3{'VA"ڨDk:ZH hөSzKcZ$t%$[+;הb^笄^'>YzH]-y<mj|e8[=1K9ކlgd@2zCHŜ#fYۯ:[Ogv(MѶt1ܲÙlRt}EWhsmg?|x K}E%^ce_sU7[BrV;X?6.3 ^P M$2}ao 4eh[G< fn4L]3(CDsML+Pz]!^+lZ Ώ+! z]Y` H챌x_eNzKrV0e]MUeZ:ȵuXwIWB=NLj6`a[HpA :134*\YF3@pE"uHX:6CF :~?c;޸:V9gFe+vKô9"VF*Aw l G2z rҳӐM >z!M=r.֕N% G^FJ%,QW PLv-ѮRVd\1|Ch Ca=HYRldž- +K(Y+.ˏ AG5929GɮE2dIhAEz\?}K'N)iUh<٩BYH*Dҿ>7Jχΐ9_ Zb݅#sR}yH{J23uhl釃7%E\yk'3$0F?0ˀTIJ1S,yWRYDڎT=j%_s=ˤD;]B'S*IMz 6झ&;OFYuzhywo)iԆO&lFsb-EJVC!JXw-G9:w@5t!f#o ,vx6pR%Ɠ=R+e&6@j9t+0w8,򅕬APd*ވ=KP'b)uݶLTn.YCpA 4Fu*Ń=g,=uExNLL>h6lmm2aoU(nkk %2n3YI|DY+υԹ^\ Ra9!|ԅel2Qa2X[QM1p9C5s:`ITR^lBmuYObEggR u#{oN`, 0q-GEL0,r#C`\A;H*f$ȭ 5Y+!< % 8HRT[#鲞oH=/ T:dMUQyh̄JQ )9 Oi`B"0nNnFJri3TZߕ9PfZrDbw:`?bHҮ.&87HBC"8*7(a kkn*]4K48R)_Q5~ODܔٽ*(t(i0KفyCV=z?sCsX`4PJ]{a- ?*AU7(%C  3A6J2J6-`f|\ Py;#C)PwǺIl̏P B[ؠǑJ8Dc1~>1ʣ?.N:rDkYJt FIXSlUƇ?jB]R2UsMxf(yt* ~ #3n;guH~:*?^U]b6*\ } ՏSl P# 06:˂u>tT$5`X2Dntub7(f"ۼYJCbInIY.zJ*^^^Z2.\^v rjcjY zJO)%]}it VOGMM9h2&Z3sɤHFa"7tPŌX31,@,"1{ӅJ[.2if@ MLyAsKzO?m.^4r#̧htŠZ@.C QByF~>|vZ-ȬתvD VSPcsAܜS/8"%TEϸ!/^`駡]&жs"@kݦVH6%;܎]r”=O0ZQy2ZC+YC 8iQ,atm+%M?SMQKN<"'Er w&{ s'.?^~u8c\.6Ӳ$l<na|tL]RpaQbV0<,`rlFRl>W/4KsΊ/dbyYw՜Yzby )m>l" 4-_hgao/uR_)J`GL|߅K7k8}=ҡZGJ7%ߛ_&aLdNHSx hW9.);<~S\m3MtzڞNjDh9T`4;C~1 "j+l79Ux" V y][;'I!b%Q%L4np'8[URWj]ȶ=E`)ϻ'~((Do2ηa~}$8 ?P A8-oș)G(X''\ piNfZ$݄x+…ǥ|Vڷ$[Ⱥ&4cly!H8OzW2cYK$"{WtOd~(7ͤ[G0Q iC1ti},}\ J/O=2 P>\u}-=>wV\"3} ẈId, 疴zG%x/1Y:7[nI&G)#EO)D}`~ZV%'ꂷ ~p~:l$gGHLU] ,K'.점wt(PjdY@D0C庶;v1W}ѥr鶚#W(ϔ4?l= Y0{ d.,XS&*cUhTI-0fKxH 5{q}2J~#3 $gUF|( +^ͭҷPS5к}Lx\)&z֠PT=frL>Y)5z m\OZ.I:nS9˾}FN3qyS(=Ig(RdLNdF2E|sxQrFUcgj" >6x )GzݓʠHr)1Ώ3Ѣ' nO} zj;sF.Iβtn<wY;|~"R|$,Smbvv0W!wU@&?$ d9Bc9 Dmxd&*hX{~TCnȸphWy}i`hu7<l` 1YIUM \/h"<9VziԀM58 A|> O} dX/+!#x!&uw$ d~L#tpRtľUK>DsTyJl,9B#:פ<#VĘD5ǯ?9MqjkQ ޮEq{ d@rڙ2𨕩y&E_zNLO(T϶y*:& FJ: 6\U'S ﳹXĄ "Ƒ!/)> RY[2uOTH(C6\̲ :ڜv) (0Kerί9DY8Uusn/K"zQeڽÊKd#5:ij/urN,}Fo?c{fu͗(S٭OIkM(LڲT^;J.ۤ =[ 񸁅ݒԵc}PФJ(捜tR^U9z|Z%e}3lXY<+*QڵcDsۻ;%dhri^ې\+~_[?Aɡ,VLZ9 Zjff4n_uZNffl;miq=>P>SPKE.|=p֗ 3Yw#"ׄnXT.:-oܖyzWVY5>4Te^ڡos]ČB Tyiz_3HV;^syxM*g>y;B劄GnJ2|B2 $R,ڬFޏPiqI3M]l4lXf@o~X7L &4wk}i#8\-9ƝxړgG/0nT3݁9RUo[m4hNQx^']et7= EZ}|zvά+p<7Q V}t#Yd' 7>Ghڑn惃;dԤ|{iDÄx/,ʆT"ݞo6j:+",W,QR|R޹\8Ocx , B2-.".!OUAyEFD)PyM73-']8䑷k^3q؝>KĬP-ݗSdg;`wΐ.6{pO00)4yL.C0vU 7&s5_P/~Tc;b RXㅂp KGi_WXfK?\+ix\)7ʺvʿ5ry+p!l ȴJf5 bJp"?%1P~¼5T/>yJL0smdr[ο/[`!މ?l]y5Uq7͖"ϖ_j% 6ռ{v"v9rXK#OtCw8yIrҐFEcM›WAAaAV#Łn*AN& O-F"],:\ p/K4:2J~"=D`wzE`F'C<'Ć0"1αk+"GTϔ{,$#eKxu/9TH' fdQN}ULԸj ڕkv,p$%yDXLxvֿ-±&9l[ M*̿!aLmaptree/data/oregon.bird.names.rda0000755000176000001440000001265312052524053016662 0ustar ripleyusersu[[SǶdgĘٻvD /#Iٔ P0cC9l:n#3l~*euOrQ OY#4T@$zO=S2V2Ę%6[BC|VƹYRO,aQ.#[}Y[HeakQ>bZE1gݘbd/ad2QDXS̊9]tD΋WS>06J,b~Π. B#nɴЧyK&<4,aS墒*%`JZTf%ͽk8em(sّ+6S?a=;c'r B%FXmpr6;k?<:1L&v~&/uĚz난v<+aר*^SOXZ\_ˬYO6e"rͷ2`erZ Nkvadvco8D>{ew9,mhA\¹#Ml: Aw. 謴Z3i[cXU X"Yu|dI3?ᐕ̔Oy:لe#?6]Wͺt +W9\qVS|r.rDdu,+'s6Z[ft aJ|li(o% dU](;)Ƥgu%S6j<SЛT촍CP ' Ϻ~3L!2$9]#)pYnB43k=r gf`DkU5RNsF'`c\DG(ԈX28#HDv''‰rRe]Yf}2 v׻4hDQK܃61=5Y(*2jbl;W0U5|3h6^s?i.H n^5t.*0H* j b&yƀZHPW[XnTd?ͦ`ʝ*+pUԛ U [R9gNzl=P%_F 1T˵d¨wYApY+SD6ZNnDaWK&ʾr \:}/u? z`d}Z>ELa7s.LfMiMjHl.ݪq9[lؗH9:բ 'VR NDd/^c:0[pVwiIXulYD:b,e#G 7I[!V{˶Q7hu:e)"7\ڧ S9TpI8 [ؼu^ pp6Z5&4{@6ù% _cti:C;CKI>jv0Fjs} G;E'fn2Myz72%?ipFT[ #N?yA[A#+)eeƾ92lk_y15vͺC4NJDz6d= Uw=հȝ6n|OB6=ke} ûOݮ1lȐ[M BuðNHMZB)$<2=꾴~5_E7U%v*:My;t'_ڡ ǜ+) T=u9z6,䘼A?f`#8͝'ŵ Rg,jYGK[7 ec{SOc'^dTҢ<Р?cpakMy?܃Pi?-p=X<G7]=(;QN덉#-m6G(ꂳ'IG]>M*g-MuYm LFSv/tϝGɺ) W_wU6yKKFocɕ̩BTMF:{GRjvXA[Qj%KR"+;;s54QOv6 R!fZ *~J&__(#n2479|B"DgM^քKMp0u3)c~Q(!T%=}ϭqt2> ¦'}LbV>/A\sm3EʭAhee*NN7kW(Gpcڅrٛpr,+je\W_e6ΜNi},HBVP\T9g78R}0 [6瘗P. 6x&e,_6,ŃXKf(1]. 4WS*ZVlI89lG9}e;\,;l6 <)UK'm}A?wM3"!C=gioSVA3NJBr4M*!vL윢99Mm*Z ޺;'|S*ybP:'yS?%"VFV:&iN>X )ҩ37W9sNqgv" "!G ^YJ67ls؆OxfǶv>릏C )H/bz=LTߖ$%u{p`ŸLW7<fW7Q^` euuU:ƭ1eL3=eÌ9{Zo ="L6/iÐ8*0y(N%C*b`:j[܂brvxeHGԸøB^]Ksnn iفzvs:{kc(AEl%7=v]pޒ\ݖh7-:Iq!E$6=}ED/05)~o9A{)C޷O(u# >`y~;l =9{ AHk:k#mg>kH0k׳B佇縷#: nz(@N\b{Bڈ ċxQ\sD!u`S[>L# gcuC'c?..}Ua!:X=ʿߏ=ϙ7=^7}: 9`ֱdo ^`Lp o{ol9 ~<8r9C/BA^ѿB=0屄B<(s4gQIH:އȡ=F8@N|5g 9 N*}̇-mػ}癄A<(s 's-~~~Bvȗ<_<#5X珹^yc? @drFσF<`q;iY!,ϑ+{U !|΋ou`S iϺN{oqZ5r >{ ķ{֞{A9 ':'^':'~\ܟ9/?N{V{{{=?*{wso} Nc@!oABY6{Og{׉Yc48f%!W7 G@IAmaptree/data/oregon.grid.tab.gz0000644000176000001440000004370012052524053016176 0ustar ripleyusersmM.d[VDb فlO?Mq\bW= DžOW[kZ~5^VXOl|5uϴ13Ofg3>ԟYzO)Ue9B7QNc-g)㱖)WGRek̩"wvgY8fZom8f5)۵GefeuOVu=_e>燐2ۮf~ O=^b==:GiM}hd_}`nËR:Jk)~~=rֲ{:[:O]6eec6e5{=Oﴜ7uׁUBeg{~/[׾{=uͳ΋ 3l,^<}m:g؀:HH&+K 'Osz֏s6}>Oy~f<54q=&83uoM6N6 {&GՓoE_6\^ϭA`|~@EO2[c/ kmW}1'skk;˦9f`&+3h3 Uy~}9v?hy~N6moe.ion; }~m,{_B!;ϩs>#Q&b[eM5{myntE{siz8cih5-ԛ(w1:JV)VDEaql9y.Dz!iH)NY-A'G=5Mbgd1 Ti;6$¤b`5kUb \d<+ZiObbTOAލw?˦80a YDQZ] \ U(hŻ QsO4[3,(͚If"ClќȥOÊj=/"6'PG]f6]Sk3qOQ9e2s0VأzI]UqB7ׄ3JҾ{5qY+W #mA{@#+oVfز.$ 0sd7ؔ'x,قȀ`mpVmu{6kMMCJUlq)dޣ099!B|VZ@SU3]kjt&bE5-Wd 4P%2s[}mymB`cjtg# 9f[ЙLwåw` #x*=tcG (io(C!}5FUȥ*:R8 [~ ^ ҭ:hY-s+\:*9WJeaS#̦,/fg6 )+TlxW @gmU^Zu!':Om R/^\ӗ [fƾ$W4f/ $*Pٗ4-iEe "!~AJI8ZYMa)KtUfxR|kScg[oTŜe/\./Uh ۃ@c.ؽ?,NYȼWFolK|6PךHnM"0F|m;'+~xِXwN ϼ-.E̕"Mcv{3 XKMlT۰(j$iǚI6]Yo3Sosh $Tn$nZC~fpEn5*I Yv,Cα,vDf_.v9yh՗|4jͤEz k 'g734342.ZZG,kk|əaebk^C3YFr?4+;+!W$!_a(9#?ofZ07-7\l |%tFrm=ѯMiɔaY6F;Y &r׾mTp*^igR!5D^immӴ327%n,*1{V~$63o6o f9ĤOPpiA1RX,k[} JG:cш51v{E{Enp[6M_|'B NghgPZ@%cK)DA δΰBS~ֈ} iz T}aqj4DaYlW8u6F!+/ԭI62]nSVe'd44F[P}%;d_5֨l$:b3cM\{^ؼׅ{}?N?{-"'P?Jɞ,LlV%d>#Q[IO?}6ј c 969vоY17bZ 9[1l V_te^Θ~uAbv;G5 n=l(Q ;V`Zf>gfzBBzPf8]L6d_7wͨVCa}ZjA#VmMF\,6bX̢B<86eM͔#j1"E茨\=lndPE-C^K3,L,6F$<'d1ؚJҞ-OMh_ƛ1N#q-xRe&$g-/[^`#& ձײG.M,BلAFi Tڷff{'.Nc_6L|͠˾TibéSKbZ/lʾt72T܃dǨW(((,7F[X+MQٗ&T( 0{ÌuӰR-%f:P,۠ⴭQU{VMy_6 #JN6棕 [l)tZrgk6$xC2,.!{lʾt72swC=.=,7d,7,7F[$iךּŋȦٗr"IgHh1`$I>-. lQa+,E^". XSK{-,iԄG^6F[XULJm^ =h p  ۚGֻdX^*l `hnxE]^HeCCM]' @@R(þyR}Ϭeux o '0t6kqW8#Di1Ya˥RLd5ޛhKōԽhJNxv)0GwSWXB`b hKō+vK)n~x8G JaGLj$+$fv+a8Q:/ϙ~NPӹ5ǀ[kţޜMutuc, %Spn;b_;:ufL iS[Ot"Ib  jAbDJ#:1ٗȀYi,mZlYPBQ3!Y@éd+Ąrb#&݁ɬ<ԐabPxT*$!AKҐIvp//:UY<6Fj_<:= -[,7/ ]M%:ѳ8thtpњcHWUb~#*݁:ˠT Nuf͢3 Xe'`&XA5J̝妱4%#?SfC9asۈ6: xefۏ^=bߣ"}Xz51u>MBg8-bxyLZW҇Z@֔9P}lKq=8\h M8nMcl2@|yBՉqMDˑN$# 0yAನ1/*T2-V.,!Ҝb簚7ΡZZtkV_3SvH3sd 3SG, 6,'Ҫdnk+ 6/${Y"ZShqu0ݠh Lz8NNnM'e{A.I$]dmmb"^EFORQ٣!c%yN`,!<:Jd^9Z ceP=sn4aKSOZ0[8؞%S5ėԙگf^o|l ֚eQ;pki<·_,qV WGڔgףY T3G^@h#.N E7~V̺Їx\* ؎K~\B_6E%y#?ـhB$]$ڕx|S1%Fy5bڗ}?#Й^Q%>d\uA(dJ)WnƔ&IUi c$HݐhңR%I+YdT [REDrEK QJY0p]% l(!z5[/e"B$aF_y/Ǡ /Gen 'g329UhF)4^MEEQUк:5|%An75h4^.9V(ֲ.K"&K- YiH]dyWA$9ǚ"z2fQ]SI"3e&G$'ٖWy)ٓD=It/J(dde{"|W|i$be+۳D؄eðTt{jm WܣHlzEdPK%1P*NP )w{ TŞ %A(ٮ,sJG%>(Oif=_~|rrPehD[lEI4x0p ;CuqT'ExGY0V&5~UͥRU g`RnC[ߤYEZ9doDi] e[ [< "'JlQIg}^tI4`'ΪnhvJUzlQ Ś(DfE@e&$!hYst_pخ3NklmYV'@U'3q& |#?Ձ&``Ղf/߄YEVR1:Ꮑ `1^xT&,4[\ʣ^ 0"y`&fSzzjSihD_TUQUyaěR ܪԧQinqoUl~W?D>.%&ɔ/ ԕꗁV_*eaCN^ްLYe/G6 4'r\3ڭ Oޔ٤uHGRe!t|m6NJf{V%4Ia&.2j]cÀ⃶~}dSٮfA~%eHAKQDl"sb  D d^'W!H3ΣXbJ[gKDXKb& Şe$sDY#(c5#uTZLDyIHsٜ2T6eۼپ)UA|7\TdmQ( jL#34.y ~LM' K@!whYH޳R H\%VۥlQ4H՛S,&%à dQwyU"9!hd|Z̄qiA^J½MKv#ԟ(oTpYݖ͋NmfEuO{F^ZvB!⒘D%6uAb$N@o]ը{ 93GXؓڦujju >}/Ⅾl۳EP;p|JhJ,D]RkmiZLL]ADAƄm Oo.HDE%Њmۼ_nWK|I(ٜYG,ET'٢|0ĭv8$Wq ELjl 7 JI,71pg.:Kh:/E/loԭn3꣉B1FVi,J0 тIL8 7`"#Jl`Sب@IpL`允8u'n}tߥt[Spt%@D;#5tv& dEIT2L"|a[jsRν[y"ShAbgɢ P~ mD`x%=4Uh6U/%F˳.@XMa!c㶵YPLzG:&-),BB&rLCGP o5iץ{ Fy.Z0^ tG;&91Y'2ԁʹaP=Rqk=kJ1lz%{Өw6MC'-eNi52[=}^p?^iah6ϟW}xeteZ-;k|6D`L9g4)gy{s29r669CïouiM5]3rJ9G+u|f(50s(d+G$DG_&2RC'1m%)CrCyWeW}! C?ݩ֪ync^|?ԟV Uh$%,3=3,zSXW6RHȶ^9$IDG|&RNސORN-ҁ  A~g[ =”Mbo >\*[)87#^<7ޟr©/h+u{JQެ (4C'1r&G54r4ɢK ,ҤIL.UHm,.0 ;q<K&тi.^oNBMdt$j"#QJ'nt|L hPKH?uKSјú\f)hבڔ=[C SP) /.W3Ad]"sn^f 򟂐xAra[nZ^5X5 ݽ_ݙkKB4_S֣:=muF̗Mdݳ-G)l~>̩xC^tY!AWX*D. j*} g M%Eץ!lIa=R~9J GMWCygn.m^6e%;ȡ~x£/K&qm]mt>Fn"K&24nH>: AΈM$ۅ^,WMb|R&]yVU:ʡt h848[M$to"(>mڲq@V!@J@q/w6MeVu&wxۭ\-p+H'ٕΨBzm=壂Cg'~?= :8 IN`VYNV_z8lh+5TZ;Mn XA8ٮR%˪Wj}Ҩ?i[Fj5§]I__E{ {Z2ga+1 QFb]ҥ_X..“lQ+PV_R9EoK]l6'ʌPt i|KYV~w.uIb^eJL&~~ya=o ͺIs4J=ǜKNz«:׫pgGNp%hQx$MaQ(VM@T43KL'rtţ5D^,`1?M72Wub¡KZ~lKwYZw&=!FP,Eߨ&fǝ"ܫL(тڌv4Ua27N5%H0 6B<:hd% ,vs'n؉t/xEI%i{=|h/ RIf]k缁~rN$}dQǮ`~+Rmђ6]r'mIt/3k64Gn6)Ն Dͮ+ eW]@Y D"  # zEOSXNbwVM<*5k_:<κV TJ< œAj<ٮi3vQ><MgccϝغuIS@` kZd)K`JD̆ }C,~)ϓx }ˢs{4r@Od|z&iZ/P7R{{z"! Гm霛=%z"ٻFގh u`U*= %ӓA:=ٮnrym{^tlÎԍHգ֥&h3 ss J?^vK6:͓u/G'>٤]eSwX Ve'O8( 8Zl{>wҶ[LwJ_ƠC{Tm %WPb e:asm\|/SQ;/lA[Ck?70q\(U0y<7ݟǯ$T.~U"7w%ʄ]UJR~OŊ3eǺ)2O4 2[땲l|WPc / ɡ=XgQ`vVfFy~sYِO .i#qUXD 8CIP=KϛaW)_)c7tIΦDU/24$"I(2@ܛrzn:r:rFϹ9 MѴ51-qգ9~`WF?7ez:{.PJ1@eT isS.xnUdSN`cAdХFSŮW& J#Iٖ3DSO9*JXѨUIx vߔEr!XPAd"BK<6yܹ)H)g$*ѢO9Ct!pУZtjɜ8hdDsGAJ9WU f~]0A!̨"y\~B"lP 8KQ_<8E}< UA\* t3N2!zx*٠H 3=)c1 2S%lq6XVTꉏ!GgfW RDQe=Vx* 3}3NZqD)!SL6T8; >2/#~8>87 e(>8H}q].>kaLg#KǕq~ѾA٢go8dN. tBNT8fr|2/s~mwsy3J9(}_* lj TQ( .|:xhqV\>(%o,\s( QHQ)aJNmE9]64],|P⪢3Z|sՕs( QsJ'SrVs$!FҙdsNg#bU9k pj2}U8*Lq~.I!RJT,在 c9(7[>5p*As1îkۿf "bDNg ˕ݜ0 d쭮WA)P C+*BeMgkGs}T$DYRv}9 #B ;"U_u$NP⡺3[|t:m)x@ DcyDTU,Au_93:BE/@&P!3 .21*Q<1Äٖ׾t^H@(!͋kUS$! !Je[y=wܞ~u .!D{3 ϣ0'2[XHJB$,zqJ1RlԼVJE[֣dMCJ|%-l-uj:4(AHSiN  C zPW̑l k}澪JGhS5EMR`KeӥZRf.^6ãy ]b!.RyH TV#usec胊P B%N? jfGYW~72"X+jNUuƨPgkmT󎞊~wPwmPkDb#9IMf\ W^a\ZB$%JJB٢ SK!Q!s$$_ oHH󭋄$$J5٢ov 1X a2BK˨wS͓-NEg)$P;t3M:c\{o"3u6ѧ.8ACΚoww,BrB12X}S%Wuk߀YbB%22FqQ͇Oi˃p3Sc TZB٢ky~A'ʠr1F"]g\=QT6$~P (K4z;Тk6 ]9f4~qŷPz%Nv4P /(R `+HňbAƒzA9A\<(Y}sMf)!.`NRٙߧh~x`~x`xjP*JA6_5db_khq|ef>7kz%ܕ$ , A:>Rmg ee:.bP$)EK4ߎJ/?wzMta|9.I/GpFjAN PW3tf qL&>zAh"`{iƸS1jLmy]!A)B3 mgH1ʤ_v$J ^ZHƬWh3RCވN@&* 6 4]\3yS\_V[%cHrAևӾZԡ= D#F 2׽9ĂR3$?{Hr6fyf++N뜆^P P 1RAZ .Vs(Э1'%;.LGC?1l 8~1J,`qaHVXzs̹W@KV A@!۝N$o'!Zp)TP׍hZdO5 .eM]㞾AUa66rVɬ#X ,S+~Ը屎?SZ!fSdp u&>Dĸq7=AWKqY='oY8b@p&,P68m(Gr֦d)hA @1s|Hgx)G.W?٦_s&fxR sTcH$h0Viv(C' ?wfW!b 1.-Wn\YHРHE+s_~%UCO #+,~ɋSk \y:\rrNO2?^7;vqƂ+N۔luHK['&slR2{.r74bt{.{Ư<8o+z% "i (U2pBFmneG@Q'r :ɖJL<*nӉ)EgÜnԻ`v t%ث҉Atb"!4*c5;t#0HJ>%-v˙Љe΃yà`'%3yr G[ϻo G'9}Л%jxOlSr %[_'Z7F@.gt*f-*j9mS"y! hhE hQK`[c8Ig&bTvN+-f/L9\*msv%PxS y%HfB2]gT(lbg8=7 @' W4+1$j8_p-/­~_*81F /cdLhcb3S*8÷.1"ca >.n(4i/N!>N NMoW GC$MWNRL(1.^s'U+<}3Fy=3![Xt*uVxoaYM 5ֻ%/;gEٙ[rM<[x dhK.oՖ\(OmC&Pr{|b9:9O3p-$`%qmI|܊8%/pIQeʳԄEIˋljWaA*;|,xѲ}-OEhpV=-ߣmaptree/MD50000644000176000001440000000246112054615042012251 0ustar ripleyusersce9fdcd5eae009589b2d425b0800671e *DESCRIPTION 96b8fdd473d3e74e506bf4a7e0c34289 *NAMESPACE 8d435511854a0366bdf3badbe84c3851 *R/maptree.R aa11a32db42cf81c5bacdf9683f3f1f3 *data/oregon.bird.dist.tab.gz b3e8e5448df04125e040affcbe758c1e *data/oregon.bird.names.rda 10db1e8e08cb53e1c204350fc74cac31 *data/oregon.border.tab.gz 750d9287d376cda46508ce4357665d20 *data/oregon.env.vars.tab.gz 499088ec2fc2220fa46cc7d24c4b5bab *data/oregon.grid.tab.gz 49c0c2d3288722afe30fc7c2f5e34343 *inst/README 457422e10819054ad485909e09761b42 *man/clip.clust.Rd c247500dc997d801b70c5eb46ebaa5b3 *man/clip.rpart.Rd cdfc5d4bb29205c25d171e2676ad782b *man/draw.clust.Rd b4573c62b6c8299c3834e79c4e7c3952 *man/draw.tree.Rd 303406d5f6f31cb9b84ba682e4ed09d8 *man/group.clust.Rd c87ce83789f46b9649b8756ff9687b33 *man/group.tree.Rd 03c0b2c3e815546d0608e89cf7e05721 *man/kgs.Rd 49e0055af5cd335cc27e9d49a576b52a *man/map.groups.Rd bfed4f892eb34198b97d2c7cc6309d2f *man/map.key.Rd 4f553cc9dd155a2d2198bed6288c6634 *man/ngon.Rd c7ae4b8e28c3f73aea3f65f54767ac0c *man/oregon.bird.dist.Rd c878887c8105d6f57087e9486d4a7093 *man/oregon.bird.names.Rd 5dec01b3f58a41e68927f465847dcd1d *man/oregon.border.Rd c87cf05aa54b447aec6612f382913bf7 *man/oregon.env.vars.Rd 9deb11d0a10eff86e53856b5743289b5 *man/oregon.grid.Rd 239680e7d948eb158fbf339a01d7e8fd *man/twins.to.hclust.Rd maptree/man/0000755000176000001440000000000012054212461012507 5ustar ripleyusersmaptree/man/map.groups.Rd0000755000176000001440000000572612054212365015111 0ustar ripleyusers\name{map.groups} \alias{map.groups} \title{Map Groups of Observations} \description{ Draws maps of groups of observations created by clustering, classification or regression trees, or some other type of classification. } \usage{ map.groups (pts, group, pch=par("pch"), size=2, col=NULL, border=NULL, new=TRUE) } \arguments{ \item{pts}{matrix or data frame with components \code{"x"}, and \code{"y"} for each observation (see details).} \item{group}{vector of integer class numbers corresponding to \code{pts} (see details), and indexing colors in \code{col}.} \item{pch}{symbol number from \code{par("pch")} if < 100, otherwise parameter \code{n} for ngon.} \item{size}{size in cex units of point symbol.} \item{col}{vector of fill colors from \code{\link{hsv}}, \code{\link{rgb}}, etc, or if \code{NULL}, then use \code{\link{rainbow}}.} \item{border}{vector of border colors from \code{\link{hsv}}, \code{\link{rgb}}, etc, or if \code{NULL}, then use \code{\link{rainbow}}.} \item{new}{if \code{TRUE}, call \code{\link{plot.new}}.} } \details{ If the number of rows of \code{pts} is not equal to the length of \code{group}, then (1) \code{pts} are assumed to represent polygons and \code{\link{polygon}} is used, (2) the identifiers in \code{group} are matched to the polygons in \code{pts} through \code{names(group)} and \code{pts$x[is.na(pts$y)]}, and (3) these identifiers are mapped to dense integers to reference colours. Otherwise, \code{group} is assumed to parallel \code{pts}, and, if \code{pch < 100}, then \code{\link{points}} is used, otherwise \code{\link{ngon}}, to draw shaded polygon symbols for each observation in pts. } \value{The vector of fill colors supplied or generated.} \author{Denis White} \seealso{ \code{\link{ngon}}, \code{\link{polygon}}, \code{\link{group.clust}}, \code{\link{group.tree}}, \code{\link{map.key}} } \examples{ data (oregon.bird.names, oregon.env.vars, oregon.bird.dist) data (oregon.border, oregon.grid) # range map for American Avocet spp <- match ("American avocet", oregon.bird.names[["common.name"]]) group <- oregon.bird.dist[,spp] + 1 names(group) <- row.names(oregon.bird.dist) kol <- gray (seq(0.8,0.2,length.out=length (table (group)))) map.groups (oregon.grid, group=group, col=kol) lines (oregon.border) # distribution of January temperatures cuts <- quantile (oregon.env.vars[["jan.temp"]], probs=seq(0,1,1/5)) group <- cut (oregon.env.vars[["jan.temp"]], cuts, labels=FALSE, include.lowest=TRUE) names(group) <- row.names(oregon.env.vars) kol <- gray (seq(0.8,0.2,length.out=length (table (group)))) map.groups (oregon.grid, group=group, col=kol) lines (oregon.border) # January temperatures using point symbols rather than polygons map.groups (oregon.env.vars, group, col=kol, pch=19) lines (oregon.border) } \keyword{hplot} \keyword{cluster} \keyword{tree} maptree/man/oregon.bird.names.Rd0000755000176000001440000000202212054212423016305 0ustar ripleyusers\name{oregon.bird.names} \alias{oregon.bird.names} \title{Names of Bird Species in Oregon, USA} \description{ Scientific and common names for 248 native breeding bird species in Oregon, USA. } \usage{data (oregon.bird.names)} \format{A data frame with 248 rows and 2 columns.} \details{ Row names are species element codes. Columns are \code{"scientific.name"} and \code{"common.name"}. Data are provided by The Nature Conservancy (TNC), the Oregon Natural Heritage Program (ONHP), and NatureServe. } \source{Denis White} \references{ Master, L. (1996) Predicting distributions for vertebrate species: some observations, \emph{Gap Analysis: A Landscape Approach to Biodiversity Planning}, Scott, J.M., Tear, T.H., and Davis, F.W., editors, American Society for Photogrammetry and Remote Sensing, Bethesda, MD, pp. 171-176. TNC, \url{http://nature.org/} ONHP, \url{http://natureserve.org/nhp/us/or/} NatureServe, \url{http://natureserve.org/} } \seealso{ \code{\link{oregon.bird.dist}} } \keyword{datasets} maptree/man/twins.to.hclust.Rd0000755000176000001440000000103112054212461016062 0ustar ripleyusers\name{twins.to.hclust} \alias{twins.to.hclust} \title{Converts agnes or diana object to hclust object} \description{ Alternative to \code{\link{as.hclust}} that retains cluster data. } \usage{ twins.to.hclust (cluster) } \arguments{ \item{cluster}{object of class \code{twins}.} } \details{ Used internally in with \code{\link{clip.clust}} and \code{\link{draw.clust}}. } \value{hclust object} \author{Denis White} \seealso{ \code{\link{hclust}}, \code{\link[cluster]{twins.object}} } \keyword{manip} \keyword{cluster} maptree/man/clip.rpart.Rd0000755000176000001440000000267212054212314015063 0ustar ripleyusers\name{clip.rpart} \alias{clip.rpart} \title{Prunes an Rpart Classification or Regression Tree} \description{ Reduces a prediction tree produced by \code{\link{rpart}} to a smaller tree by specifying either a cost-complexity parameter, or a number of nodes to which to prune. } \usage{ clip.rpart (tree, cp=NULL, best=NULL) } \arguments{ \item{tree}{object of class \code{rpart}.} \item{cp}{cost-complexity parameter.} \item{best}{number of nodes to which to prune.} If both \code{cp} and \code{best} are not \code{NULL}, then \code{cp} is used. } \details{ A minor enhancement of the existing \code{\link{prune.rpart}} to incorporate the parameter \code{best} as it is used in the (now defunct) \code{prune.tree} function in the old \pkg{tree} package. See example. } \value{Pruned tree object of class \code{rpart}.} \author{Denis White} \seealso{ \code{\link[rpart]{rpart}}, \code{\link[rpart]{prune.rpart}} } \examples{ library (rpart) data (oregon.env.vars, oregon.border, oregon.grid) draw.tree (clip.rpart (rpart (oregon.env.vars), best=7), nodeinfo=TRUE, units="species", cases="cells", digits=0) group <- group.tree (clip.rpart (rpart (oregon.env.vars), best=7)) names(group) <- row.names(oregon.env.vars) map.groups (oregon.grid, group) lines (oregon.border) map.key (0.05, 0.65, labels=as.character(seq(6)), size=1, new=FALSE, sep=0.5, pch=19, head="node") } \keyword{manip} \keyword{cluster} maptree/man/group.tree.Rd0000755000176000001440000000142512054212347015100 0ustar ripleyusers\name{group.tree} \alias{group.tree} \title{Observation Groups for Classification or Regression Tree} \description{ Alternative to \code{tree[["where"]]} that orders groups from left to right in draw order. } \usage{ group.tree (tree) } \arguments{ \item{tree}{object of class \code{rpart} or \code{tree}.} } \details{ Normally used with \code{\link{map.groups}}. See example. } \value{Vector of rearranged \code{tree[["where"]]}} \author{Denis White} \seealso{ \code{\link[rpart]{rpart}}, \code{\link{map.groups}} } \examples{ library (rpart) data (oregon.env.vars, oregon.grid) group <- group.tree (clip.rpart (rpart (oregon.env.vars), best=7)) names(group) <- row.names(oregon.env.vars) map.groups (oregon.grid, group=group) } \keyword{manip} \keyword{tree} maptree/man/oregon.bird.dist.Rd0000755000176000001440000000320312054212414016147 0ustar ripleyusers\name{oregon.bird.dist} \alias{oregon.bird.dist} \title{Presence/Absence of Bird Species in Oregon, USA} \description{ Binary matrix (1 = present) for distributions of 248 native breeding bird species for 389 grid cells in Oregon, USA. } \usage{data (oregon.bird.dist)} \format{A data frame with 389 rows and 248 columns.} \details{ Row names are hexagon identifiers from White et al. (1992). Column names are species element codes developed by The Nature Conservancy (TNC), the Oregon Natural Heritage Program (ONHP), and NatureServe. } \source{Denis White} \references{ Master, L. (1996) Predicting distributions for vertebrate species: some observations, \emph{Gap Analysis: A Landscape Approach to Biodiversity Planning}, Scott, J.M., Tear, T.H., and Davis, F.W., editors, American Society for Photogrammetry and Remote Sensing, Bethesda, MD, pp. 171-176. White, D., Preston, E.M., Freemark, K.E., Kiester, A.R. (1999) A hierarchical framework for conserving biodiversity, \emph{Landscape ecological analysis: issues and applications}, Klopatek, J.M., Gardner, R.H., editors, Springer-Verlag, pp. 127-153. White, D., Kimerling, A.J., Overton, W.S. (1992) Cartographic and geometric components of a global sampling design for environmental monitoring, \emph{Cartography and Geographic Information Systems}, \bold{19}(1), 5-22. TNC, \url{http://nature.org/} ONHP, \url{http://natureserve.org/nhp/us/or/} NatureServe, \url{http://natureserve.org/} } \seealso{ \code{\link{oregon.env.vars}}, \code{\link{oregon.bird.names}}, \code{\link{oregon.grid}}, \code{\link{oregon.border}} } \keyword{datasets} maptree/man/clip.clust.Rd0000755000176000001440000000207512054212302015057 0ustar ripleyusers\name{clip.clust} \alias{clip.clust} \title{Prunes a Hierarchical Cluster Tree} \description{ Reduces a hierarchical cluster tree to a smaller tree either by pruning until a given number of observation groups remain, or by pruning tree splits below a given height. } \usage{ clip.clust (cluster, data=NULL, k=NULL, h=NULL) } \arguments{ \item{cluster}{object of class \code{hclust} or \code{twins}.} \item{data}{clustered dataset for hclust application.} \item{k}{desired number of groups.} \item{h}{height at which to prune for grouping.} At least one of \code{k} or \code{h} must be specified; \code{k} takes precedence if both are given. } \details{ Used with \code{\link{draw.clust}}. See example. } \value{Pruned cluster object of class \code{hclust}.} \author{Denis White } \seealso{ \code{\link{hclust}}, \code{\link[cluster]{twins.object}}, \code{\link{cutree}}, \code{\link{draw.clust}} } \examples{ library (cluster) data (oregon.bird.dist) draw.clust (clip.clust (agnes (oregon.bird.dist), k=6)) } \keyword{manip} \keyword{cluster} maptree/man/draw.clust.Rd0000755000176000001440000000272312054212323015070 0ustar ripleyusers\name{draw.clust} \alias{draw.clust} \title{Graph a Hierarchical Cluster Tree} \description{ Graph a hierarchical cluster tree of class \code{twins} or \code{hclust} using colored symbols at observations. } \usage{ draw.clust (cluster, data=NULL, cex=par("cex"), pch=par("pch"), size=2.5*cex, col=NULL, nodeinfo=FALSE, cases="obs", new=TRUE) } \arguments{ \item{cluster}{object of class \code{hclust} or \code{twins}.} \item{data}{clustered dataset for hclust application.} \item{cex}{size of text, par parameter.} \item{pch}{shape of symbol at leaves, par parameter.} \item{size}{size in cex units of symbol at leaves.} \item{col}{vector of colors from \code{\link{hsv}}, \code{\link{rgb}}, etc, or if \code{NULL}, then use \code{\link{rainbow}}.} \item{nodeinfo}{if \code{TRUE}, add a line at each node with number of observations included in each leaf.} \item{cases}{label for type of observations.} \item{new}{if \code{TRUE}, call \code{\link{plot.new}}.} } \details{ An alternative to \code{\link{pltree}} and \code{\link{plot.hclust}}. } \value{The vector of colors supplied or generated.} \author{Denis White} \seealso{ \code{\link[cluster]{agnes}}, \code{\link[cluster]{diana}}, \code{\link{hclust}}, \code{\link{draw.tree}}, \code{\link{map.groups}} } \examples{ library (cluster) data (oregon.bird.dist) draw.clust (clip.clust (agnes (oregon.bird.dist), k=6)) } \keyword{hplot} \keyword{cluster} maptree/man/map.key.Rd0000755000176000001440000000416012054212374014351 0ustar ripleyusers\name{map.key} \alias{map.key} \title{Draw Key to accompany Map of Groups} \description{ Draws legends for maps of groups of observations. } \usage{ map.key (x, y, labels=NULL, cex=par("cex"), pch=par("pch"), size=2.5*cex, col=NULL, head="", sep=0.25*cex, new=FALSE) } \arguments{ \item{x, y}{coordinates of lower left position of key in proportional units (0-1) of plot.} \item{labels}{vector of labels for classes, or if \code{NULL}, then integers \code{1:length(col)}, or \code{1}.} \item{size}{size in cex units of shaded key symbol.} \item{pch}{symbol number for \code{\link{par}} if < 100, otherwise parameter \code{n} for \code{\link{ngon}}.} \item{cex}{pointsize of text, \code{\link{par}} parameter.} \item{head}{text heading for key.} \item{sep}{separation in cex units between adjacent symbols in key. If \code{sep=0}, assume a continuous scale, use square symbols, and put labels at breaks between squares.} \item{col}{vector of colors from \code{\link{hsv}}, \code{\link{rgb}}, etc, or if \code{NULL}, then use \code{\link{rainbow}}.} \item{new}{if \code{TRUE}, call \code{\link{plot}}.} } \details{ Uses \code{\link{points}} or \code{\link{ngon}}, depending on value of \code{pch}, to draw shaded polygon symbols for key. } \value{The vector of colors supplied or generated.} \author{Denis White} \seealso{ \code{\link{ngon}}, \code{\link{map.groups}} } \examples{ data (oregon.env.vars) # key for examples in help(map.groups) # range map for American Avocet kol <- gray (seq(0.8,0.2,length.out=2)) map.key (0.2, 0.2, labels=c("absent","present"), pch=106, col=kol, head="key", new=TRUE) # distribution of January temperatures cuts <- quantile (oregon.env.vars[["jan.temp"]], probs=seq(0,1,1/5)) kol <- gray (seq(0.8,0.2,length.out=5)) map.key (0.2, 0.2, labels=as.character(round(cuts,0)), col=kol, sep=0, head="key", new=TRUE) # key for example in help file for group.tree map.key (0.2, 0.2, labels=as.character(seq(6)), pch=19, head="node", new=TRUE) } \keyword{hplot} \keyword{aplot} maptree/man/oregon.env.vars.Rd0000755000176000001440000000306112054212441016031 0ustar ripleyusers\name{oregon.env.vars} \alias{oregon.env.vars} \title{Environmental Variables for Oregon, USA} \description{ Distributions of 10 environmental variables for 389 grid cells in Oregon, USA. } \usage{data (oregon.env.vars)} \format{A data frame with 389 rows and 10 columns.} \details{ Row names are hexagon identifiers from White et al. (1992). Variables (columns) are \tabular{ll}{ bird.spp \tab number of native breeding bird species\cr x \tab x coordinate of center of grid cell\cr y \tab y coordinate of center of grid cell\cr jan.temp \tab mean minimum January temperature (C)\cr jul.temp \tab mean maximum July temperature (C)\cr rng.temp \tab mean difference between July and January temperatures (C)\cr ann.ppt \tab mean annual precipitation (mm)\cr min.elev \tab minimum elevation (m)\cr rng.elev \tab range of elevation (m)\cr max.slope \tab maximum slope (percent) } } \source{Denis White} \references{ White, D., Preston, E.M., Freemark, K.E., Kiester, A.R. (1999) A hierarchical framework for conserving biodiversity, \emph{Landscape ecological analysis: issues and applications}, Klopatek, J.M., Gardner, R.H., editors, Springer-Verlag, pp. 127-153. White, D., Kimerling, A.J., Overton, W.S. (1992) Cartographic and geometric components of a global sampling design for environmental monitoring, \emph{Cartography and Geographic Information Systems}, \bold{19}(1), 5-22. } \seealso{ \code{\link{oregon.bird.dist}}, \code{\link{oregon.grid}}, \code{\link{oregon.border}} } \keyword{datasets} maptree/man/oregon.grid.Rd0000755000176000001440000000347712054212451015230 0ustar ripleyusers\name{oregon.grid} \alias{oregon.grid} \title{Hexagonal Grid Cell Polygons covering Oregon, USA} \description{ Polygon borders for 389 hexagonal grid cells covering Oregon, USA, in \code{\link{polygon}} format. } \usage{data (oregon.grid)} \format{A data frame with 3112 rows and 2 columns (the components \code{"x"} and \code{"y"}).} \details{ The polygon format used for these grid cell boundaries is a slight variation from the standard R/S format. Each cell polygon is described by seven coordinate pairs, the last repeating the first. Prior to the first coordinate pair of each cell is a row containing NA in the \code{"y"} column and, in the \code{"x"} column, an identifier for the cell. The identifiers are the same as the row names in \code{\link{oregon.bird.dist}} and \code{\link{oregon.env.vars}}. See \code{\link{map.groups}} for how the linkage is made in mapping. These grid cells are extracted from a larger set covering the conterminous United States and adjacent parts of Canada and Mexico, as described in White et al. (1992). Only cells with at least 50 percent of their area contained within the state of Oregon are included. The map projection for the coordinates, as well as the point coordinates in \code{\link{oregon.env.vars}}, is the Lambert Conformal Conic with standard parallels at 33 and 45 degrees North latitude, with the longitude of the central meridian at 120 degrees, 30 minutes West longitude, and with the projection origin latitude at 41 degrees, 45 minutes North latitude. } \source{Denis White} \references{ White, D., Kimerling, A.J., Overton, W.S. (1992) Cartographic and geometric components of a global sampling design for environmental monitoring, \emph{Cartography and Geographic Information Systems}, \bold{19}(1), 5-22. } \keyword{datasets} maptree/man/group.clust.Rd0000755000176000001440000000201412054212341015260 0ustar ripleyusers\name{group.clust} \alias{group.clust} \title{Observation Groups for a Hierarchical Cluster Tree} \description{ Alternative to \code{\link{cutree}} that orders pruned groups from left to right in draw order. } \usage{ group.clust (cluster, k=NULL, h=NULL) } \arguments{ \item{cluster}{object of class \code{hclust} or \code{twins}.} \item{k}{desired number of groups.} \item{h}{height at which to prune for grouping.} At least one of \code{k} or \code{h} must be specified; \code{k} takes precedence if both are given. } \details{ Normally used with \code{\link{map.groups}}. See example. } \value{Vector of pruned cluster membership} \author{Denis White} \seealso{ \code{\link{hclust}}, \code{\link[cluster]{twins.object}}, \code{\link{cutree}}, \code{\link{map.groups}} } \examples{ data (oregon.bird.dist, oregon.grid) group <- group.clust (hclust (dist (oregon.bird.dist)), k=6) names(group) <- row.names(oregon.bird.dist) map.groups (oregon.grid, group) } \keyword{manip} \keyword{cluster} maptree/man/draw.tree.Rd0000755000176000001440000000501712054212332014674 0ustar ripleyusers\name{draw.tree} \alias{draw.tree} \title{Graph a Classification or Regression Tree} \description{ Graph a classification or regression tree with a hierarchical tree diagram, optionally including colored symbols at leaves and additional info at intermediate nodes. } \usage{ draw.tree (tree, cex=par("cex"), pch=par("pch"), size=2.5*cex, col=NULL, nodeinfo=FALSE, units="", cases="obs", digits=getOption("digits"), print.levels=TRUE, new=TRUE) } \arguments{ \item{tree}{object of class \code{rpart} or \code{tree}.} \item{cex}{size of text, par parameter.} \item{pch}{shape of symbol at leaves, par parameter.} \item{size}{if \code{size=0}, draw terminal symbol at leaves else a symbol of size in cex units.} \item{col}{vector of colors from \code{\link{hsv}}, \code{\link{rgb}}, etc, or if \code{NULL}, then use \code{\link{rainbow}}.} \item{nodeinfo}{if \code{TRUE}, add a line at each node with mean value of response, number of observations, and percent deviance explained (or classified correct).} \item{units}{label for units of mean value of response, if regression tree.} \item{cases}{label for type of observations.} \item{digits}{number of digits to round mean value of response, if regression tree.} \item{print.levels}{if \code{TRUE}, print levels of factors at splits, otherwise only the factor name.} \item{new}{if \code{TRUE}, call \code{\link{plot.new}}.} } \details{ As in \code{plot.rpart(,uniform=TRUE)}, each level has constant depth. Specifying \code{nodeinfo=TRUE}, shows the deviance explained or the classification rate at each node. A split is shown, for numerical variables, as \code{variable <> value} when the cases with lower values go left, or as \code{variable >< value} when the cases with lower values go right. When the splitting variable is a factor, and print.levels=TRUE, the split is shown as \code{levels = factor = levels} with the cases on the left having factor levels equal to those on the left of the factor name, and correspondingly for the right. } \value{The vector of colors supplied or generated.} \author{Denis White} \seealso{ \code{\link[rpart]{rpart}}, \code{\link{draw.clust}}, \code{\link{map.groups}} } \examples{ library (rpart) data (oregon.env.vars) draw.tree (clip.rpart (rpart (oregon.env.vars), best=7), nodeinfo=TRUE, units="species", cases="cells", digits=0) } \keyword{hplot} \keyword{tree} maptree/man/oregon.border.Rd0000755000176000001440000000132412054212431015543 0ustar ripleyusers\name{oregon.border} \alias{oregon.border} \title{Boundary of Oregon, USA} \description{ The boundary of the state of Oregon, USA, in \code{\link{lines}} format. } \usage{data (oregon.border)} \format{A data frame with 485 rows and 2 columns (the components \code{"x"} and \code{"y"}).} \details{ The map projection for this boundary, as well as the point coordinates in \code{\link{oregon.env.vars}}, is the Lambert Conformal Conic with standard parallels at 33 and 45 degrees North latitude, with the longitude of the central meridian at 120 degrees, 30 minutes West longitude, and with the projection origin latitude at 41 degrees, 45 minutes North latitude. } \source{Denis White} \keyword{datasets} maptree/man/ngon.Rd0000755000176000001440000000213412054212402013735 0ustar ripleyusers\name{ngon} \alias{ngon} \title{Outline or Fill a Regular Polygon} \description{ Draws a regular polygon at specified coordinates as an outline or shaded. } \usage{ ngon (xydc, n=4, angle=0, type=1) } \arguments{ \item{xydc}{four element vector with \code{x} and \code{y} coordinates of center, \code{d} diameter in mm, and \code{c} color.} \item{n}{number of sides for polygon (>8 => circle).} \item{angle}{rotation angle of figure, in degrees.} \item{type}{\code{type=1} => interior filled, \code{type=2} => edge, \code{type=3} => both.} } \details{ Uses \code{\link{polygon}} to draw shaded polygons and \code{\link{lines}} for outline. If n is odd, there is a vertex at (0, d/2), otherwise the midpoint of a side is at (0, d/2). } \value{Invisible.} \author{Denis White} \seealso{ \code{\link{polygon}}, \code{\link{lines}}, \code{\link{map.key}}, \code{\link{map.groups}} } \examples{ plot (c(0,1), c(0,1), type="n") ngon (c(.5, .5, 10, "blue"), angle=30, n=3) apply (cbind (runif(8), runif(8), 6, 2), 1, ngon) } \keyword{aplot} maptree/man/kgs.Rd0000755000176000001440000000371012054212356013571 0ustar ripleyusers\name{kgs} \alias{kgs} \title{KGS Measure for Pruning Hierarchical Clusters} \description{ Computes the Kelley-Gardner-Sutcliffe penalty function for a hierarchical cluster tree. } \usage{ kgs (cluster, diss, alpha=1, maxclust=NULL) } \arguments{ \item{cluster}{object of class \code{hclust} or \code{twins}.} \item{diss}{object of class \code{dissimilarity} or \code{dist}.} \item{alpha}{weight for number of clusters.} \item{maxclust}{maximum number of clusters for which to compute measure.} } \details{ Kelley et al. (see reference) proposed a method that can help decide where to prune a hierarchical cluster tree. At any level of the tree the mean across all clusters of the mean within clusters of the dissimilarity measure is calculated. After normalizing, the number of clusters times alpha is added. The minimum of this function corresponds to the suggested pruning size. The current implementation has complexity O(n*n*maxclust), thus very slow with large n. For improvements, at least it should only calculate the spread for clusters that are split at each level, rather than over again for all. } \value{Vector of the penalty function for trees of size 2:maxclust. The names of vector elements are the respective numbers of clusters.} \references{ Kelley, L.A., Gardner, S.P., Sutcliffe, M.J. (1996) An automated approach for clustering an ensemble of NMR-derived protein structures into conformationally-related subfamilies, \emph{Protein Engineering}, \bold{9}, 1063-1065. } \author{Denis White} \seealso{ \code{\link[cluster]{twins.object}}, \code{\link[cluster]{dissimilarity.object}}, \code{\link{hclust}}, \code{\link{dist}}, \code{\link{clip.clust}}, } \examples{ library (cluster) data (votes.repub) a <- agnes (votes.repub, method="ward") b <- kgs (a, a$diss, maxclust=20) plot (names (b), b, xlab="# clusters", ylab="penalty") } \keyword{manip} \keyword{cluster} maptree/DESCRIPTION0000644000176000001440000000104412054615042013443 0ustar ripleyusersPackage: maptree Version: 1.4-7 Date: 2012-11-24 Title: Mapping, pruning, and graphing tree models Author: Denis White, Robert B. Gramacy Maintainer: Robert B. Gramacy Depends: R (>= 2.14), cluster, rpart Description: Functions with example data for graphing, pruning, and mapping models from hierarchical clustering, and classification and regression trees. License: Unlimited Packaged: 2012-11-24 18:43:40 UTC; bobby Repository: CRAN Date/Publication: 2012-11-26 07:28:04 maptree/NAMESPACE0000644000176000001440000000031212043442535013154 0ustar ripleyusers# Default NAMESPACE created by R # Remove the previous line if you edit this file # Export all names exportPattern(".") # Import all packages listed as Imports or Depends import( cluster, rpart ) maptree/inst/0000755000176000001440000000000011330432111012701 5ustar ripleyusersmaptree/inst/README0000755000176000001440000000604711330432611013600 0ustar ripleyusersChanges in contributed package maptree: 1.4-6, 28 January 2010 * fixed clip.clust and draw.clust again to force data required from either twins or hclust models * removed membership option from draw.clust because not really practical (usually drawing aggregated clusters with multiple members; complicates determining size of graphic) 1.4-5, 26 January 2009 * changed map.tree.Rd to fix \code quote issue in response to request from CRAN 1.4-4, 22 October 2007 * changed License to "Unlimited" in DESCRIPTION in response to request from CRAN 1.4-3, 15 November 2006 * fixed clip.clust and draw.clust to require data from hclust objects (that had disappeared in recent releases), and changed help files accordingly (thanks to Mikkel Grum) * removed dependence on package combinat in function kgs() as function combn() is now part of standard package utils, and changed help file accordingly 1.4-2, 10 February 2006 * fixed draw.tree to correctly label nodes when only one independent variable 1.4-1, 7 January 2006 * changed prune.clust to clip.clust and prune.rpart to clip.rpart to avoid non-generic function warning * added export and import to NAMESPACE * removed dependence on package mva, now in stats * added argument membership to draw.clust that prints members of clusters at leaves; added retention of membership in clip.clust * added function twins.to.hclust to retain data in conversion to hclust, for use in draw.clust and clip.clust * removed col="gray" option from draw.clust, draw.tree, map.groups, and map.key. Examples in map.groups use gray scale. 1.3-3, 6 March 2003 * removed call to tree.depth in draw.tree (now causing failure) 1.3-2, 22 April 2002 * draw.tree now labels factor splits correctly for rpart objects (but not for tree objects) and has an argument print.levels, default TRUE, to avoid printing levels when there are too many * kgs has new argument alpha that weights contribution of number of clusters to penalty function * draw.tree argument digits defaults to getOption("digits") 1.3-1, 8 April 2002 * new function kgs computes penalty measure for cluster trees. * draw.clust, draw.tree, and map.groups now have argument new (default TRUE) to accomodate multiple figure plots (when new=FALSE). * map.groups now maps group identifiers to dense integers for referencing color numbers. * prune.clust now returns correct components on pruned clusters, plus new component "size" having number of observations included in each pruned leaf. * draw.clust has new argument nodeinfo, which if TRUE causes the number of observations included in each leaf to be displayed (for pruned clusters). * map.key argument "lables" changed in spelling to "labels". 1.2-1, 15 March 2002 * draw.clust, draw.tree, map.key, and map.groups now use cex for sizing text and symbols. * prune.Rpart uses best argument as advertised. Thanks to Brian Ripley for identification of problem and suggestion of solution. * draw.tree now correctly displays response level for classification trees. maptree/R/0000755000176000001440000000000011330432103012126 5ustar ripleyusersmaptree/R/maptree.R0000644000176000001440000006374711330432567013745 0ustar ripleyusers# maptree package # for graphing and mapping of hierarchical clustering and # regression trees # denis white, us epa, 15 November 2006, version 1.4-3 # # function calls # ############################################################ # # clip.clust <- function (cluster, data=NULL, k=NULL, h=NULL) # # clip.rpart <- function (tree, cp=NULL, best=NULL) # # draw.clust <- function (cluster, data=NULL, cex=par("cex"), # pch=par("pch"), size=2.5*cex, col=NULL, nodeinfo=FALSE, # membership=FALSE, cases="obs", new=TRUE) # # draw.tree <- function (tree, cex=par("cex"), pch=par("pch"), # size=2.5*cex, col=NULL, nodeinfo=FALSE, units="", # cases="obs", digits=getOption("digits"), # print.levels=TRUE, new=TRUE) # # group.clust <- function (cluster, k=NULL, h=NULL) # # group.tree <- function (tree) # # kgs <- function (cluster, diss, alpha=1, maxclust=NULL) # # map.groups <- function (pts, group, pch=par("pch"), size=2, # col=NULL, border=NULL, new=TRUE) # # map.key <- function (x, y, labels=NULL, cex=par("cex"), # par=par("pch"), size=2.5*cex, col=NULL, head="", # sep=0.25*cex, new=FALSE) # # ngon <- function (xydc, n=4, angle=0, type=1) # # twins.to.hclust <- function (cluster) ############################################################ clip.clust <- function (cluster, data = NULL, k=NULL, h=NULL) # analogous to prune.tree # cluster is class hclust or twins # data is clustered dataset (provided by twins but not hclust) # k is desired number of groups # h is height at which to cut for grouping # needs k or h, k takes precedence # returns pruned cluster { if (is.null (h) && is.null (k)) stop ("clip.clust: both h=NULL, k=NULL") if (!is.null (h) && h > max (cluster$height)) stop ("clip.clust: h > max (height)") if (!is.null (k) && (k == 1 || k > length (cluster$height))) stop("clip.clust: k==1 || k=>nobs") if ("hclust" %in% class (cluster)) { if (is.null (data)) stop ("clip.clust: no data provided for hclust object") clust <- cluster } else if (inherits (cluster, "twins")) { if (! ("data" %in% names (cluster))) if (is.null (data)) stop ("clip.clust: no data provided for twins object") else cluster$data <- data clust <- twins.to.hclust (cluster) # clust <- as.hclust (cluster) } else stop("clip.clust: input not hclust or twins") merg <- clust$merge hite <- clust$height nmerg <- nrow(merg) if (!is.null (k)) keep <- rev (order (hite))[1:(k-1)] else keep <- seq (nmerg)[hite > h] numerg <- matrix (0, nrow=length (keep), ncol=2) nuhite <- rep (0, length (keep)) leaf <- 0 node <- 0 trim.clust <- function (oldnode) { a <- merg[oldnode,1] b <- merg[oldnode,2] if (match (a, keep, 0) != 0) l <- trim.clust (a) else { leaf <<- leaf + 1 l <- -leaf } if (match (b, keep, 0) != 0) r <- trim.clust (b) else { leaf <<- leaf + 1 r <- -leaf } node <<- node + 1 numerg[node,] <<- c(l,r) nuhite[node] <<- hite[oldnode] return (node) } trim.clust (length (hite)) # trim.clust(match(max(hite),hite)) numerg <- matrix (as.integer(numerg), nrow=length (numerg)/2, ncol=2) nuhite <- as.double (nuhite - min (nuhite)) nuordr <- as.double (seq (nrow (numerg) + 1)) nulabl <- as.character (nuordr) g <- group.clust (clust, k, h) if ("twins" %in% class(cluster)) data <- clust$data m <- split (rownames (data), as.factor (g)) l <- list (merge=numerg, height=nuhite, order=nuordr, labels=nulabl, method=clust$method, call=clust$call, dist.method=clust$dist.method, size=table (g), membership=m, data=data) class(l) <- class(clust) l } ############################################################ clip.rpart <- function (tree, cp=NULL, best=NULL) # modification to original prune.rpart to add best { ff <- tree$frame id <- as.integer (row.names (ff)) if (is.null (cp)) { m <- tree$cptable[, "nsplit"] m <- max (m[m < best]) m <- match (m, tree$cptable[, "nsplit"]) cp <- tree$cptable[m, "CP"] } toss <- id[ff$complexity <= cp & ff$var != ""] if (length (toss) == 0) return(tree) newx <- snip.rpart (tree, toss) temp <- pmax(tree$cptable[, 1], cp) keep <- match (unique (temp), temp) newx$cptable <- tree$cptable[keep, ] newx$cptable[max(keep), 1] <- cp newx } ############################################################ draw.clust <- function (cluster, data=NULL, cex=par("cex"), pch=par("pch"), size=2.5*cex, col=NULL, nodeinfo=FALSE, cases="obs", new=TRUE) # cluster is class hclust or twins # data is clustered dataset (provided by twins but not hclust) # cex is par parameter, size of text # pch is par parameter, shape of symbol at leaves of tree # size is in cex units for symbol at leaves of tree # if col is NULL, use rainbow() # if nodeinfo==TRUE, add a line at each leaf with number # of observations included in leaf # cases are names for cluster objects # if new=TRUE, call plot.new() # returned value is col or generated colors { if ("hclust" %in% class (cluster)) { if (is.null (data)) if ("data" %in% names (cluster)) data <- cluster$data else stop ("draw.clust: no data provided for hclust object") clust <- cluster } else if (inherits (cluster, "twins")) { if (! ("data" %in% names (cluster))) if (is.null (data)) stop ("draw.clust: no data provided for twins object") else cluster$data <- data clust <- twins.to.hclust (cluster) # clust <- as.hclust (cluster) data <- clust$data } else stop("draw.clust: input not hclust or twins") merg <- clust$merge nmerg <- nrow (merg) if (nmerg<2) stop ("draw: < 3 clusters") if (new) plot.new () hite <- clust$height cord <- order (clust$order) xmax <- nrow (merg) + 1 ymax <- max (hite) pinx <- par ("pin")[1] piny <- par ("pin")[2] xmin <- 1 box <- size * par("cin")[1] xscale <- (xmax-xmin)/pinx xbh <- xscale * box / 2 tail <- 0.2 yscale <- ymax/(piny - tail) ytail <- yscale * tail ybx <- yscale * box ymin <- - ytail xf <- 0.1 * (xmax-xmin) yf <- 0.1 * (ymax-ymin) x1 <- xmin - xf x2 <- xmax + xf y1 <- ymin - yf y2 <- ymax + yf par (usr=c(x1, x2, (y1-nodeinfo*ybx), y2)) if (is.null(col)) kol <- rainbow (xmax) else kol <- col xmean <- rep (0, nmerg) i <- 1 while (any(xmean == 0)) { if (xmean[i] == 0) { a <- merg[i,1] b <- merg[i,2] if (a<0) x1 <- cord[-a] else x1 <- xmean[a] if (b<0) x2 <- cord[-b] else x2 <- xmean[b] if (x1 != 0 && x2 != 0) xmean[i] <- mean(c(x1,x2)) } i <- i + 1 if (i > nmerg) i <- 1 } for (i in 1:nmerg) { a <- merg[i,1] b <- merg[i,2] y2 <- hite[i] if (a > 0) { x1 <- xmean[a] y1a <- hite[a] } else { x1 <- cord[-a] y1a <- y2 - ytail points (x1, y1a-ybx/2, pch=pch, cex=size, col=kol[x1]) text.default (x1, y1a-(ybx/2), as.character(-a), cex=cex) if (nodeinfo) { string <- paste (as.character (clust$size[-a]), cases) text.default (x1, y1a-1.3*ybx, string, cex=cex) } } if (b > 0) { x2 <- xmean[b] y1b <- hite[b] } else { x2 <- cord[-b] y1b <- y2 - ytail points (x2, y1b-ybx/2, pch=pch, cex=size, col=kol[x2]) text.default (x2, y1b-(ybx/2), as.character(-b), cex=cex) if (nodeinfo) { string <- paste (as.character (clust$size[-b]), cases) text.default (x2, y1b-1.3*ybx, string, cex=cex) } } lines (c(x1,x2),c(y2,y2)) lines (c(x1,x1),c(y1a,y2)) lines (c(x2,x2),c(y1b,y2)) } invisible (kol) } ############################################################ draw.tree <- function (tree, cex=par("cex"), pch=par("pch"), size=2.5*cex, col=NULL, nodeinfo=FALSE, units="", cases="obs", digits=getOption("digits"), print.levels=TRUE, new=TRUE) # tree is object of class tree # cex is par parameter, size of text # pch is par parameter, shape of symbol at leaves of tree # if size=0, draw terminal symbol at leaves # else symbol with size in cex units # if col is NULL, use rainbow() # if nodeinfo=TRUE, add a line at each node with mean value # of response, number of observations, and percent # deviance explained (or classified correct) # units are for mean value of response (if regression tree) # cases are names for observations # digits are rounding for response # if print.levels=FALSE, do not show factor levels at splits # if new=TRUE, call plot.new() # returned value is col or generated colors { if (new) plot.new () rtree <- length (attr (tree, "ylevels")) == 0 tframe <- tree$frame rptree <- length (tframe$complexity) > 0 node <- as.numeric(row.names(tframe)) depth <- floor (log (node, base=2) + 1e-07) depth <- as.vector (depth - min (depth)) maxdepth <- max(depth) x <- - depth y <- x leaves <- tframe$var == "" x[leaves] <- seq(sum(leaves)) depth <- split(seq(node)[!leaves], depth[!leaves]) parent <- match(node %/% 2, node) left.child <- match(node * 2, node) right.child <- match(node * 2 + 1, node) for(i in rev(depth)) x[i] <- 0.5 * (x[left.child[i]] + x[right.child[i]]) nleaves <- sum(leaves) nnodes <- length(node) nodeindex <- which (tframe$var != "") if (rtree) { dev <- tframe$dev pcor <- rep (0, nnodes) for (i in 1:nnodes) if (! leaves[i]) { l <- dev[node == (node[i]*2)] r <- dev[node == (node[i]*2+1)] pcor[i] <- dev[i] - l - r } pcor <- round (pcor/dev[1],3)*100 } else { crate <- rep (0, nnodes) trate <- 0 if (! rptree) { for (i in 1:nnodes) { yval <- tframe$yval[i] string <- paste('tframe$yprob[,"', as.character(yval), '"]', sep="") crate[i] <- eval(parse(text=string))[i] if (leaves[i]) trate <- trate + tframe$n[i] * crate[i] } } else { for (i in 1:nnodes) { yval <- tframe$yval[i] nlv <- floor (ncol (tframe$yval2) / 2) index <- rev (order (tframe$yval2[i, 2:(nlv+1)]))[1] crate[i] <- tframe$yval2[i, (nlv + 1 + index)] if (leaves[i]) trate <- trate + tframe$n[i] * crate[i] } } crate <- round (crate,3)*100 trate <- round (trate/tframe$n[1],3)*100 } if (is.null(col)) kol <- rainbow (nleaves) else kol <- col xmax <- max(x) xmin <- min(x) ymax <- max(y) ymin <- min(y) pinx <- par ("pin")[1] piny <- par ("pin")[2] xscale <- (xmax - xmin)/pinx box <- size * par("cin")[1] if (box == 0) xbh <- xscale * 0.2 else xbh <- xscale * box/2 chr <- cex * par("cin")[2] tail <- box + chr yscale <- (ymax - ymin)/(piny - tail) ytail <- yscale * tail if (box == 0) ybx <- yscale * 0.2 else ybx <- yscale * box ychr <- yscale * chr ymin <- ymin - ytail xf <- 0.1 * (xmax - xmin) yf <- 0.1 * (ymax - ymin) x1 <- xmin - xf x2 <- xmax + xf y1 <- ymin - yf y2 <- ymax + yf par (usr=c(x1,x2,y1,y2)) v <- as.character (tframe$var[1]) if (rptree) { sp <- tree$splits[1, ] val <- sp["index"] if (sp["ncat"] > 1) { r <- sp["index"] string <- "attributes(tree)$xlevels$" string <- paste (string, v, sep="") xl <- eval (parse (text=string)) lf <- rf <- "" for (k in 1:sp["ncat"]) if (tree$csplit[r, k] == 1) lf <- paste (lf, xl[k], sep=",") else rf <- paste (rf, xl[k], sep=",") if (! print.levels) string <- v else string <- paste (lf, "=", v, "=", rf) } else { if (sp["ncat"] < 0) op <- "<>" else op <- "><" string <- paste (v, op, val) } } else { val <- substring(as.character(tframe$splits[1, 1]), 2) string <- paste (as.character(v), "<>", val) } text.default (x[1], y[1], string, cex=cex) if (nodeinfo) { n <- tframe$n[1] if (rtree) { z <- round(tframe$yval[1], digits) r <- pcor[1] string <- paste (z," ",units,"; ",n," ",cases,"; ", r,"%",sep="") } else { z <- attr (tree, "ylevels")[tframe$yval[1]] r <- crate[1] string <- paste (z,"; ",n," ",cases,"; ",r,"%", sep="") } text.default (x[1], y[1]-ychr, string, cex=cex) } for (i in 2:nnodes) { ytop <- ychr * (as.integer(nodeinfo)+1) if (y[i] < y[i-1]) { lines(c(x[i-1], x[i]), c(y[i-1]-ytop, y[i-1]-ytop)) lines(c(x[i], x[i]), c(y[i-1]-ytop, y[i]+ychr)) } else { lines(c(x[parent[i]], x[i]), c(y[parent[i]]-ytop, y[parent[i]]-ytop)) lines(c(x[i], x[i]), c(y[parent[i]]-ytop, y[i]+ychr)) } if(! leaves[i]) { v <- as.character (tframe$var[i]) if (rptree) { if (length (tree$ordered) > 1) { k <- 1 for (j in 1:(i-1)) { m <- tframe$ncompete[j] if (m > 0) k <- k + m + 1 m <- tframe$nsurrogate[j] if (m > 0) k <- k + m } } else k <- match (i, nodeindex[-1]) + 1 sp <- tree$splits[k, ] val <- sp["index"] if (sp["ncat"] > 1) { r <- sp["index"] string <- "attributes(tree)$xlevels$" string <- paste (string, v, sep="") xl <- eval (parse (text=string)) lf <- rf <- "" for (k in 1:sp["ncat"]) if (tree$csplit[r, k] == 1) lf <- paste (lf, xl[k], sep=",") else rf <- paste (rf, xl[k], sep=",") if (! print.levels) string <- v else string <- paste (lf, "=", v, "=", rf) } else { if (sp["ncat"] < 0) op <- "<>" else op <- "><" string <- paste (v, op, val) } } else { val <- substring(as.character(tframe$splits[i, 1]), 2) string <- paste (as.character(v), "<>", val) } text.default (x[i], y[i], string, cex=cex) if (nodeinfo) { n <- tframe$n[i] if (rtree) { z <- round(tframe$yval[i], digits) r <- pcor[i] string <- paste (z," ",units,"; ",n," ",cases,"; ", r,"%",sep="") } else { z <- attr (tree, "ylevels")[tframe$yval[i]] r <- crate[i] string <- paste (z,"; ",n," ",cases,"; ",r,"%", sep="") } text.default (x[i], y[i]-ychr, string, cex=cex) } } else { if (box == 0) { lines (c(x[i], x[i]), c(y[i], y[i]+ychr)) lines (c(x[i]-xbh, x[i]+xbh), c(y[i], y[i])) } else { points (x[i], y[i], pch=pch, cex=size, col=kol[x[i]]) } if (rtree) { z <- round(tframe$yval[i], digits) text.default(x[i], y[i]-ybx, paste(z,units,sep=" "), cex=cex) } else { z <- attr (tree, "ylevels")[tframe$yval[i]] text.default(x[i], y[i]-ybx, z, cex=cex) } n <- tframe$n[i] text.default(x[i], y[i]-ybx-ychr, paste(n,cases,sep=" "), cex=cex) if (box != 0) text.default (x[i], y[i], as.character(x[i]), cex=cex) } } if (nodeinfo) { if (rtree) string <- paste("Total deviance explained =", sum(pcor),"%") else string <- paste("Total classified correct =",trate,"%") if (box == 0) text.default (mean(x),ymin-3*ychr,string,cex=1.2*cex) else text.default (mean(x),ymin-1.2*ybx,string,cex=1.2*cex) } } ############################################################ group.clust <- function (cluster, k=NULL, h=NULL) # alternative to cutree that orders groups from left to # right in draw order # cluster is class hclust or twins # k is desired number of groups # h is height at which to cut for grouping # needs k or h, k takes precedence # returns vector of membership { if (is.null (h) && is.null (k)) return (cluster$order) if (!is.null (h) && h > max (cluster$height)) stop("group.clust: h > max (height)") if (!is.null (k) && (k == 1 || k > length (cluster$height))) stop("group.clust: k == 1 || k => nobs") if ("hclust" %in% class (cluster)) clust <- cluster else if (inherits (cluster, "twins")) clust <- as.hclust (cluster) else stop("group.clust: input not hclust or twins") merg <- clust$merge hite <- clust$height ordr <- clust$order nmerg <- nrow (merg) group <- rep (0, nmerg+1) if (!is.null (k)) keep <- rev (order (hite))[1:(k-1)] else keep <- seq (nmerg)[hite > h] mark.group <- function (node, grup) { a <- merg[node,1] b <- merg[node,2] if (a < 0) group[-a] <<- grup else mark.group (a, grup) if (b < 0) group[-b] <<- grup else mark.group (b, grup) invisible() } grup <- 0 find.group <- function (node) { a <- merg[node,1] b <- merg[node,2] if (match (a, keep, 0) != 0) find.group (a) else { grup <<- grup + 1 if (a > 0) mark.group (a, grup) else group[-a] <<- grup } if (match (b, keep, 0) != 0) find.group (b) else { grup <<- grup + 1 if (b > 0) mark.group (b, grup) else group[-b] <<- grup } invisible () } find.group (length (hite)) grup <- match (grup, unique (grup[clust$order])) invisible (group) } ############################################################ group.tree <- function (tree) # alternative to tree$where that orders groups from left # to right in draw order { group <- match (tree$where, sort (unique (tree$where))) names (group) <- names (tree$where) invisible (group) } ############################################################ kgs <- function (cluster, diss, alpha=1, maxclust=NULL) # cluster is class hclust or twins # diss is class dist or dissimilarity # alpha is weight for number of clusters # maxclust is maximum number of clusters to compute for; # if NULL, use n-1 # needs {maptree} # this implementation of complexity O(n*n*maxclust); # needs memory from level to level to cut down compares # ref: Kelley LA, Gardner SP, Sutcliffe MJ. 1996. An # automated approach for clustering an ensemble of # NMR-derived protein structures into conformationally- # reated subfamilies. Protein Engineering 9:1063-1065. { spread <- function (mem, diss) { if (length (mem) > 2) comb <- combn (mem, 2) else comb <- matrix (mem, nrow=2, ncol=1) n <- ceiling (sqrt (2 * length (diss))) sp <- 0 for (k in seq (ncol (comb))) { i <- comb[1, k] j <- comb[2, k] sp <- sp + diss[n*(i-1) - i*(i-1)/2 + j-i] } sp <- sp * 2 / (n * (n-1)) sp } if ("hclust" %in% class (cluster)) clust <- cluster else if (inherits (cluster, "twins")) clust <- as.hclust (cluster) else stop("kgs: input not hclust or twins") if (class (diss) != "dist" && class (diss) != "dissimilarity") stop ("kgs: input not dist or dissimilarity") n <- length (clust$order) if (is.null (maxclust) || maxclust > (n-1)) m <- n - 1 else m <- maxclust avsp <- rep (0, m-1) for (i in 2:m) { gl <- group.clust (clust, k=i) sz <- table (gl) nsp <- sp <- 0 for (j in seq (i)) { if (sz[j] > 1) { mem <- seq (n)[gl == j] sp <- sp + spread (mem, diss) nsp <- nsp + 1 } } avsp[i-1] <- sp / nsp } avsp <- (m-1)*(avsp - min(avsp))/diff (range (avsp)) + 1 kgs <- avsp + alpha*(2:m) names (kgs) <- as.character (2:m) kgs } ############################################################ map.groups <- function (pts, group, pch=par("pch"), size=2, col=NULL, border=NULL, new=TRUE) # pts must have components "x" and "y"; # group is vector of length of number of cases (either # polygons or points) and indexes colors; # if pts are for polygons, then names(group) must match # with pts$x[is.na(pts$y)] # if nrow(pts) != length(group) then map with polygon, # else if pch < 100 map with points, # else map with ngon (..., n=pch-100) # pch is par parameter, shape of point symbol # size is in cex units of point symbol # if col is NULL, use rainbow() # if border is NULL, use fill colors (col), # else the specified color(s) # if new=TRUE, call plot.new() { n <- colnames (pts) if (! any (n == "x")) stop ("map.groups: pts has no $x") else if (! any (n == "y")) stop ("map.groups: pts has no $y") if (nrow(pts) != length(group)) if (is.null (names (group))) stop ("map.groups: group has no names") if (new) plot.new () nna <- which (! is.na (pts$y)) rx <- range (pts$x[nna]) ry <- range (pts$y[nna]) dx <- diff (rx) dy <- diff (ry) ex <- 0.02 plot.window (rx + c(-ex*dx,ex*dx), ry + c(-ex*dy,ex*dy), asp=1) dense <- sort (unique (group)) nc <- length (dense) if (is.null(col)) fkol <- rainbow (nc) else fkol <- rep (col, nc) if (is.null(border)) bkol <- fkol else bkol <- rep (border, nc) if (nrow (pts) != length (group)) { i <- pts$x[is.na (pts$y)] j <- match (i, as.integer (names (group))) polygon (pts$x, pts$y, lwd=0.1, col=fkol[match (group[j], dense)], border=bkol[match (group[j], dense)]) } else if (pch < 100 | mode(pch) == "character") points (pts$x, pts$y, col=fkol[match (group, dense)], pch=pch, cex=size*1.5) else apply (data.frame (x=pts$x, y=pts$y, d=size*25.4*par("cex")*par("cin")[1], c=I(fkol[match (group, dense)])), 1, ngon, n=pch-100, type=1) invisible (fkol) } ############################################################ map.key <- function (x, y, labels=NULL, cex=par("cex"), pch=par("pch"), size=2.5*cex, col=NULL, head="", sep=0.25*cex, new=FALSE) # x,y are lower left coordinates of key # in proportional units (0-1) # labels is vector of labels for classes, or if NULL, # then integers 1:length(col), or "1" # cex is par parameter, size of text # if pch < 100, use points for symbol, # else ngon (..., n=pch-100) # size is in cex units for key symbols # if col is NULL, use rainbow() # cex is par parameter, size of text # head is text heading for key # sep is separation in cex units between adjacent symbols # if sep=0 assume continuous scale and use gon=4 # and put lables at breaks between squares # if new=TRUE, call plot # returned value is col or generated colors { if (is.null (labels)) if (is.null (col)) labels <- as.vector ("1") else labels <- as.character (seq (length (col) - 1)) nsym <- length (labels) if (sep == 0) nsym <- nsym - 1 if (is.null (col)) kol <- rainbow (nsym) else kol <- col if (new) plot(c(0,1), c(0,1), type="n", axes=FALSE, xlab="", ylab="") oldadj <- par ("adj") par (adj=0) u <- par ("usr") ex <- par ("pin")[1] ey <- par ("pin")[2] uxr <- u[2] - u[1] uyr <- u[4] - u[3] halfx <- (size * par("cin")[1]) / 3 xstep <- halfx + 0.05 ystep <- (size + sep) * par("cin")[2] / 2.5 px <- x * uxr + u[1] py <- y * uyr + u[3] hx <- halfx * uxr / ex dx <- xstep * uxr / ex dy <- ystep * uyr / ey qx <- px qy <- py - dy if (sep == 0) { for (i in 1:nsym) { qy <- qy + dy points (qx, qy, pch=15, cex=size*1.1, col=kol[i]) text (qx+dx, qy - dy/2, labels[i], cex=cex) } text (qx+dx, qy + dy/2, labels[nsym+1], cex=cex) } else for (i in 1:nsym) { qy <- qy + dy if (pch < 100 | mode(pch) == "character") points (qx, qy, col=kol[i], pch=pch, cex=size) else ngon (c(qx, qy, size=15*size*par("cin")[1], col=kol[i]), n=pch-100, type=1) text (qx+dx, qy, labels[i], cex=cex) } if (length (head) > 0) { qy <- qy + (dy * length (grep ("$", head))) if (sep == 0) qy <- qy + 0.5 * dy text (qx-hx, qy, head, cex=cex) } par (adj=oldadj) invisible (kol) } ############################################################ ngon <- function (xydc, n=4, angle=0, type=1) # draw or fill regular polygon # xydc a four element vector with # x and y of center, d diameter in mm, and c color # n number of sides of polygon, n>8 => circle # if n odd, vertex at (0,d/2), else midpoint of side # angle is in degrees by which to rotate the figure # type=1 => interior filled, type=2 => edge # type=3 => both { # scale factors for d based on n (ignoring angle) # n = 3, s = (2 + sqrt(3)) / 4 = 0.9330127 # n = 4, s = 1 / sqrt(2) = 0.7071068 # n = 5, s = (1 + cos(.2*pi)) / 2 = 0.9045085 # n = 6, s = sqrt(3) / 2 = 0.8660254 u <- par ("usr") p <- par ("pin") d <- as.numeric (xydc[3]) inch <- d / 25.4 s <- 1 switch (n, stop ("ngon: n=1"), stop ("ngon: n=2"), s <- 0.9330127, s <- 0.7071068, s <- 0.9045085, s <- 0.8660254) inch <- inch / s rad <- inch*((u[2]-u[1])/p[1])/2 ys <- inch*((u[4]-u[3])/p[2])/2/rad if (n > 8) n <- d*4 + 1 th <- pi*2/n costh <- cos (th) sinth <- sin (th) x <- y <- rep (0,n+1) if (n %% 2) { x0 <- 0 y0 <- rad } else { x0 <- -rad*sin(th/2) y0 <- rad*cos(th/2) } a <- pi*angle/180 x[1] <- x0*cos(a) - y0*sin(a) y[1] <- x0*sin(a) + y0*cos(a) for (i in 2:(n+1)) { xl <- x[i-1] yl <- y[i-1] x[i] <- xl*costh - yl*sinth y[i] <- xl*sinth + yl*costh } x <- x + as.numeric (xydc[1]) y <- y*ys + as.numeric (xydc[2]) if (type %% 2) polygon (x, y, col=xydc[4], border=0) if (type %/% 2) lines (x, y, col=xydc[4]) invisible () } ############################################################ twins.to.hclust <- function (cluster) { if (! inherits(cluster,"twins")) stop ("twins.to.hclust: input not twins") merg <- cluster$merge hite <- cluster$height ordr <- cluster$order nuhite <- rep (0, length(hite)) hite.clust <- function (node) { a <- merg[node,1] b <- merg[node,2] if (a < 0) l <- rep(match(-a,ordr),2) else l <- hite.clust(a) if (b < 0) r <- rep(match(-b,ordr),2) else r <- hite.clust(b) if (r[1] - l[2] == 1) nuhite[node] <<- hite[l[2]] return (c(l[1],r[2])) } n <- length(hite) hite.clust (n) l <- list() l[[1]] <- merg l[[2]] <- nuhite l[[3]] <- ordr l[[4]] <- cluster$order.lab l[[5]] <- "unknown" l[[6]] <- attr(cluster,"Call") l[[7]] <- "unknown" l[[8]] <- cluster$data names(l) <- c("merge","height","order","labels","method", "call","dist.method","data") class(l) <- "hclust" l }