%let name=murder; filename odsout '.'; /* SAS Imitation of... http://www.nytimes.com/imagepages/2006/04/28/nyregion/20060428_HOMICIDE_CHART.html */ /* Use maps.counties, rather than maps.uscounty, because it shows more detail. */ data my_map; set mapsgfk.us_counties (where=(statecode='NY' and county in (85,47,81,5,61,)) drop=resolution); run; data mapdata; format median_income dollar8.0; input county median_income; datalines; 85 75000 61 55000 81 37000 5 19500 47 18000 ; run; data murderlocs; input long lat; by_var=1; long=long*-1; datalines; 73.820 40.670 74.120 40.570 74.110 40.580 74.130 40.580 74.200 40.520 74.201 40.550 74.181 40.545 74.120 40.610 74.125 40.636 74.133 40.636 74.138 40.633 74.158 40.637 74.168 40.635 74.160 40.633 74.088 40.637 74.088 40.635 74.080 40.633 74.073 40.613 74.073 40.611 74.078 40.618 74.063 40.601 74.068 40.608 74.090 40.581 74.088 40.588 73.800 40.588 73.808 40.592 73.805 40.586 73.812 40.590 73.750 40.595 73.758 40.603 73.755 40.596 73.762 40.603 73.752 40.598 73.756 40.609 73.751 40.596 73.769 40.601 73.776 40.606 73.771 40.592 73.789 40.600 73.841 40.575 73.805 40.656 73.812 40.660 73.750 40.665 73.758 40.673 73.755 40.666 73.762 40.673 73.752 40.678 73.756 40.679 73.791 40.666 73.769 40.671 73.776 40.676 73.771 40.662 73.789 40.670 73.841 40.645 73.770 40.675 73.778 40.693 73.775 40.686 73.782 40.693 73.772 40.688 73.776 40.699 73.781 40.686 73.789 40.691 73.756 40.696 73.751 40.682 73.799 40.690 73.825 40.676 73.822 40.680 73.841 40.665 73.790 40.695 73.788 40.713 73.795 40.702 73.792 40.723 73.782 40.708 73.796 40.719 73.791 40.710 73.791 40.721 73.796 40.726 73.791 40.702 73.799 40.710 73.770 40.695 73.768 40.713 73.775 40.702 73.772 40.723 73.762 40.708 73.776 40.719 73.771 40.710 73.771 40.721 73.776 40.726 73.771 40.702 73.779 40.710 73.810 40.685 73.798 40.703 73.815 40.692 73.812 40.713 73.802 40.698 73.816 40.709 73.811 40.700 73.811 40.711 73.816 40.716 73.811 40.692 73.819 40.700 73.880 40.665 73.878 40.683 73.885 40.672 73.822 40.678 73.886 40.689 73.881 40.680 73.881 40.672 73.889 40.670 73.920 40.655 73.918 40.673 73.925 40.662 73.922 40.693 73.862 40.668 73.926 40.679 73.921 40.670 73.919 40.681 73.926 40.686 73.921 40.662 73.929 40.660 73.930 40.659 73.928 40.675 73.935 40.668 73.932 40.692 73.872 40.661 73.936 40.675 73.931 40.676 73.929 40.689 73.936 40.682 73.931 40.665 73.939 40.661 73.950 40.645 73.948 40.663 73.955 40.652 73.952 40.683 73.892 40.658 73.956 40.669 73.951 40.660 73.949 40.671 73.966 40.676 73.951 40.652 73.959 40.650 73.960 40.649 73.958 40.665 73.965 40.658 73.962 40.682 73.892 40.651 73.966 40.665 73.961 40.666 73.959 40.679 73.966 40.672 73.961 40.655 73.969 40.651 73.940 40.635 73.938 40.653 73.945 40.642 73.942 40.673 73.882 40.648 73.946 40.659 73.941 40.650 73.939 40.661 73.956 40.666 73.941 40.642 73.949 40.640 73.950 40.639 73.948 40.655 73.955 40.648 73.952 40.672 73.882 40.641 73.956 40.655 73.951 40.656 73.949 40.669 73.956 40.662 73.951 40.655 73.959 40.651 73.910 40.635 73.908 40.653 73.915 40.642 73.912 40.683 73.916 40.652 73.911 40.650 73.909 40.661 73.926 40.666 73.921 40.642 73.919 40.640 73.920 40.636 73.918 40.655 73.925 40.628 73.922 40.672 73.926 40.655 73.921 40.656 73.919 40.629 73.926 40.662 73.921 40.655 73.929 40.661 73.950 40.615 73.948 40.623 73.955 40.622 73.952 40.663 73.892 40.628 73.956 40.632 73.951 40.630 73.949 40.641 73.966 40.646 73.951 40.620 73.959 40.620 73.960 40.616 73.958 40.635 73.962 40.652 73.892 40.621 73.966 40.625 73.961 40.636 73.973 40.615 73.986 40.642 73.971 40.635 73.969 40.641 73.980 40.635 73.978 40.643 73.985 40.642 73.982 40.663 73.922 40.648 73.986 40.652 73.981 40.650 73.979 40.661 73.996 40.666 73.991 40.640 73.989 40.640 73.990 40.636 73.988 40.655 73.995 40.628 73.992 40.672 73.912 40.641 73.996 40.675 73.991 40.656 74.003 40.635 73.999 40.662 73.999 40.655 74.009 40.651 73.988 40.578 73.995 40.577 74.015 40.579 74.096 40.579 74.002 40.578 74.009 40.573 73.965 40.579 73.966 40.577 73.978 40.579 73.972 40.578 73.969 40.576 73.980 40.599 73.986 40.592 73.998 40.599 73.990 40.598 73.993 40.596 74.086 40.600 73.945 40.599 73.946 40.591 73.958 40.599 73.952 40.598 73.949 40.592 74.020 40.619 74.026 40.612 74.028 40.619 74.020 40.618 74.023 40.616 74.036 40.620 74.020 40.649 74.026 40.642 74.020 40.643 74.028 40.649 74.020 40.655 74.023 40.646 74.026 40.655 73.960 40.639 73.966 40.636 73.960 40.633 73.968 40.639 73.960 40.642 73.963 40.636 73.966 40.641 73.940 40.639 73.946 40.636 73.940 40.623 73.948 40.639 73.940 40.632 73.943 40.636 73.946 40.641 73.930 40.641 73.936 40.646 73.930 40.633 73.938 40.642 73.930 40.642 73.933 40.646 73.936 40.651 73.928 40.649 73.926 40.646 73.929 40.631 73.928 40.648 73.921 40.642 73.923 40.642 73.921 40.651 73.900 40.641 73.906 40.646 73.900 40.633 73.908 40.642 73.900 40.642 73.903 40.646 73.906 40.651 73.898 40.649 73.896 40.646 73.899 40.631 73.898 40.648 73.891 40.642 73.893 40.642 73.891 40.651 73.880 40.661 73.886 40.666 73.880 40.653 73.888 40.662 73.880 40.662 73.883 40.666 73.886 40.671 73.878 40.669 73.876 40.666 73.879 40.651 73.878 40.668 73.871 40.662 73.873 40.662 73.871 40.671 73.920 40.691 73.926 40.696 73.920 40.683 73.928 40.692 73.920 40.692 73.923 40.696 73.926 40.701 73.918 40.699 73.916 40.696 73.919 40.681 73.918 40.698 73.911 40.692 73.913 40.692 73.911 40.701 73.940 40.691 73.946 40.686 73.940 40.673 73.948 40.692 73.940 40.682 73.943 40.696 73.951 40.691 73.956 40.676 73.952 40.673 73.953 40.692 73.959 40.662 73.951 40.696 73.959 40.681 73.942 40.676 73.958 40.663 73.943 40.692 73.953 40.672 73.941 40.686 73.959 40.711 73.942 40.706 73.958 40.693 73.943 40.722 73.953 40.702 73.941 40.716 73.979 40.701 73.978 40.683 73.973 40.692 73.962 40.696 73.963 40.712 73.961 40.706 74.012 40.679 74.008 40.672 74.012 40.711 74.013 40.723 74.011 40.712 74.002 40.716 74.003 40.728 74.001 40.726 74.001 40.718 74.003 40.723 74.002 40.712 73.992 40.716 73.998 40.722 73.993 40.726 74.009 40.738 74.008 40.743 74.006 40.732 73.992 40.736 73.998 40.742 73.993 40.746 73.992 40.746 73.989 40.748 73.988 40.733 73.986 40.742 73.978 40.752 73.973 40.756 73.992 40.766 73.989 40.768 73.988 40.753 73.986 40.762 73.978 40.772 73.973 40.776 73.982 40.786 73.979 40.788 73.978 40.773 73.976 40.782 73.968 40.792 73.963 40.796 73.962 40.806 73.959 40.815 73.958 40.793 73.956 40.802 73.948 40.810 73.943 40.816 73.942 40.836 73.939 40.845 73.938 40.823 73.936 40.832 73.928 40.840 73.923 40.846 73.938 40.849 73.922 40.841 73.928 40.813 73.926 40.832 73.911 40.830 73.913 40.856 73.942 40.846 73.931 40.855 73.931 40.833 73.938 40.842 73.923 40.850 73.929 40.856 73.931 40.859 73.925 40.851 73.924 40.833 73.921 40.842 73.919 40.820 73.911 40.866 73.922 40.846 73.911 40.855 73.911 40.833 73.918 40.842 73.903 40.850 73.909 40.856 73.911 40.859 73.905 40.851 73.904 40.833 73.901 40.842 73.899 40.830 73.891 40.866 73.942 40.756 73.931 40.765 73.931 40.743 73.938 40.752 73.923 40.760 73.919 40.766 73.931 40.769 73.935 40.761 73.924 40.743 73.921 40.752 73.909 40.740 73.908 40.776 73.942 40.756 73.931 40.765 73.931 40.743 73.938 40.752 73.923 40.760 73.919 40.766 73.931 40.769 73.935 40.761 73.924 40.743 73.921 40.752 73.909 40.740 73.908 40.776 73.882 40.736 73.871 40.745 73.871 40.723 73.878 40.732 73.863 40.740 73.859 40.746 73.871 40.749 73.875 40.741 73.864 40.723 73.861 40.732 73.849 40.720 73.912 40.726 73.901 40.735 73.901 40.713 73.908 40.722 73.893 40.730 73.889 40.736 73.901 40.739 73.905 40.731 73.894 40.723 73.891 40.722 73.893 40.760 73.832 40.756 73.821 40.765 73.821 40.743 73.828 40.752 73.809 40.766 73.821 40.769 73.825 40.761 73.814 40.743 73.791 40.752 73.799 40.740 73.842 40.786 73.847 40.780 73.831 40.795 73.836 40.791 73.831 40.773 73.838 40.782 73.780 40.780 73.750 40.760 73.740 40.768 73.740 40.718 73.744 40.720 73.734 40.735 73.839 40.705 73.848 40.705 73.848 40.715 73.841 40.695 73.851 40.695 73.851 40.705 73.861 40.690 73.881 40.866 73.871 40.896 73.876 40.866 73.889 40.879 73.878 40.871 73.871 40.878 73.871 40.881 73.868 40.862 73.866 40.866 73.871 40.899 73.868 40.877 73.862 40.875 73.858 40.881 73.848 40.882 73.842 40.886 73.851 40.899 73.848 40.897 73.856 40.895 73.866 40.899 73.862 40.893 73.861 40.892 73.848 40.861 73.838 40.862 73.832 40.866 73.841 40.879 73.838 40.877 73.846 40.875 73.856 40.879 73.852 40.873 73.851 40.872 73.888 40.859 73.878 40.852 73.872 40.851 73.881 40.869 73.878 40.878 73.896 40.860 73.896 40.865 73.882 40.853 73.891 40.862 73.888 40.889 73.878 40.882 73.882 40.881 73.881 40.899 73.888 40.908 73.896 40.890 73.896 40.895 73.892 40.883 73.891 40.892 73.898 40.819 73.888 40.812 73.891 40.829 73.878 40.838 73.896 40.820 73.896 40.825 73.892 40.813 73.901 40.822 73.852 40.811 73.822 40.814 73.832 40.819 73.835 40.821 73.852 40.824 73.857 40.829 73.862 40.825 73.865 40.831 73.872 40.834 73.877 40.839 73.882 40.835 73.885 40.841 73.882 40.844 73.887 40.842 73.892 40.845 73.895 40.858 73.902 40.844 73.907 40.842 73.912 40.845 73.915 40.858 73.912 40.854 73.917 40.852 73.922 40.855 73.925 40.868 73.922 40.814 73.927 40.812 73.932 40.815 73.935 40.828 73.932 40.804 73.937 40.802 73.942 40.805 73.945 40.818 73.932 40.814 73.937 40.812 73.942 40.815 73.945 40.828 73.919 40.811 73.915 40.818 73.928 40.813 73.921 40.825 73.929 40.831 73.925 40.828 73.928 40.823 73.931 40.825 73.919 40.841 73.915 40.838 73.918 40.833 73.921 40.835 73.900 40.851 73.905 40.828 73.908 40.823 73.915 40.835 73.880 40.871 73.885 40.848 73.888 40.843 73.895 40.855 73.880 40.881 73.885 40.858 73.888 40.863 73.895 40.855 73.880 40.891 73.885 40.868 73.888 40.853 73.895 40.845 73.890 40.881 73.895 40.878 73.898 40.863 73.895 40.855 73.900 40.881 73.905 40.878 73.908 40.863 73.905 40.855 73.900 40.861 73.905 40.858 73.908 40.843 73.895 40.835 73.905 40.885 73.909 40.888 73.905 40.905 73.901 40.908 73.924 40.888 73.820 40.878 73.840 40.848 73.880 40.792 73.927 40.793 73.927 40.810 73.927 40.820 73.923 40.815 73.913 40.825 73.918 40.829 73.908 40.839 73.903 40.839 73.900 40.839 73.895 40.839 73.895 40.849 73.895 40.869 73.895 40.872 73.899 40.872 73.903 40.870 ; run; %let seed=12345; /* Ok - since I don't have real data, I'm going to "simulate" some properties/categories for each murder. (In your case, you'd have real data, and would not need to do this part. */ data murderlocs; set murderlocs; barnum=1; random=ranuni(&seed); if random <= .08 then victim_agerange=1; else if random <= (.08+.30) then victim_agerange=2; else if random <= (.08+.30+.39) then victim_agerange=3; else if random <= (.08+.30+.39+.18) then victim_agerange=4; else victim_agerange=5; random=ranuni(&seed); if random <= .08 then killer_agerange=1; else if random <= (.08+.36) then killer_agerange=2; else if random <= (.08+.36+.40) then killer_agerange=3; else if random <= (.08+.36+.40+.14) then killer_agerange=4; else killer_agerange=5; random=ranuni(&seed); if random <= .82 then victim_sex=1; else victim_sex=2; random=ranuni(&seed); if random <= .93 then killer_sex=1; else killer_sex=2; random=ranuni(&seed); if random <= .60 then victim_race=1; else if random <= (.60+.27) then victim_race=2; else if random <= (.60+.27+.09) then victim_race=3; else victim_race=4; random=ranuni(&seed); if random <= .61 then killer_race=1; else if random <= (.61+.28) then killer_race=2; else if random <= (.61+.28+.07) then killer_race=3; else killer_race=4; random=ranuni(&seed); if random <= .54 then vict_rel=1; else if random <= (.54+.24) then vict_rel=2; else if random <= (.54+.24+.15) then vict_rel=3; else vict_rel=4; random=ranuni(&seed); if random <= .40 then murd_loc=1; else if random <= (.40+.23) then murd_loc=2; else if random <= (.40+.23+.19) then murd_loc=3; else if random <= (.40+.23+.19+.16) then murd_loc=4; else murd_loc=5; random=ranuni(&seed); if random <= .66 then murd_wep=1; else if random <= (.66+.22) then murd_wep=2; else if random <= (.66+.22+.06) then murd_wep=3; else murd_wep=4; run; proc sql noprint; create table murderlocs as select *, count(*) as murder_count from murderlocs; select count(*) into :murder_count from murderlocs; quit; run; %let murder_count=%trim(&murder_count); /* Since I don't have exactly as many obsns as the original, I'm hard-coding their number, so my imitation will 'appear' to be like theier. But with real data, you would use the above code to count the obsns. */ %let murder_count=1,662; goptions device=png; goptions gunit=pct htitle=4 ftitle="albany amt/bold" htext=2.7 ftext="albany amt"; goptions ctext=gray33; /************** Map ******************/ data murder_dot; set murderlocs; anno_flag=1; run; /* project the map, and the annotation (this 'straightens' the selected state map) */ data combined; set my_map murder_dot; run; proc gproject data=combined out=combined latlong eastlong degrees dupok; id state county; run; data my_map murder_dot; set combined; if anno_flag=1 then output murder_dot; else output my_map; run; /* Do this after the gproject, so the long strings won't slow down the gproject */ data murder_dot; set murder_dot; length function style $35 color $8 text $20 html $400; html= 'title='||quote('Long,Lat = '||trim(left(longitude))||', '||trim(left(latitude)))|| ' href="murder_info.htm"'; xsys='2'; ysys='2'; hsys='3'; when='a'; function='pie'; rotate=360; size=.6; color='black'; style='psolid'; output; color='graycc'; style='pempty'; html=''; output; run; data name_anno; length color $ 8 text $ 20; xsys='3'; ysys='3'; hsys='3'; when='a'; function='label'; size=3.25; position='5'; color=''; x=51; y=26.5; text='Brooklyn'; output; x=73; y=53.3; text='Queens'; output; x=76; y=91.0; text='Bronx'; output; x=46; y=75.0; text='Manhattan'; output; color='grayee'; x=27; y=22.9; text='Staten Island'; output; run; goptions nodisplay; *goptions xpixels=750 ypixels=650; goptions xpixels=742 ypixels=651; pattern1 color=grayee; pattern2 color=graycc; pattern3 color=grayaa; pattern4 color=gray66; pattern5 color=gray44; legend1 label=(font="albany amt" /* height=3pct */ position=top j=c 'Median household income' j=c 'in each county (2000)') offset=(7,7) shape=bar(.15in,.15in) across=1 position=(left middle inside) mode=share order=(' $75,000' ' $55,000' ' $37,000' ' $19,500' ' $18,000'); /* Whereas, the following order= statements don't work... */ /* order=(75000, 55000, 37000, 19500, 18000); order=('$75,000' '$55,000' '$37,000' '$19,500' '$18,000'); footnote h=3 " "; */ proc gmap data=mapdata map=my_map anno=murder_dot; id county; choro median_income / discrete coutline=gray33 legend=legend1 anno=name_anno name="mainmap"; run; goptions xpixels=300 ypixels=225; goptions gunit=pct htitle=4.7 ftitle="thorndale amt/bold" htext=2.7 ftext="albany amt"; goptions ctext=gray33; title1 ls=1.5 j=l move=(+1.5,+0) "Three Years of Murder in New York City"; title2 j=l move=(+1.5,+0) "There were &murder_count murders reported in New York City from 2003 through 2005, strongly"; title3 j=l move=(+1.5,+0) "concentrated in poorer neighborhoods. Here are some other aspects of murder in the city."; footnote1 j=l h=2.5 move=(+1.5,+0) "Sources: New York Police Department; United States Census data analyzed by the"; footnote2 j=l h=2.5 move=(+1.5,+0) "Queens College Department of Sociology" c=red "(proof-of-concept using contrived data)"; proc gslide name="titles"; run; /****************** Motive ********************/ data motives; format percent percent7.0; input percent motive $ 5-30; datalines; .28 Dispute .23 Drugs .12 Domestic violence .11 Robbery or burglary .09 Revenge .07 Gang .07 Other .03 Unknown ; run; data motives; set motives; length my_html $300; my_html= 'title='||quote(trim(left(motive))||': '||trim(left(put(percent,percent7.0))))|| ' href="murder_info.htm"'; run; goptions htext=3.5; data motiv_anno; set motives; xsys='2'; ysys='2'; hsys='3'; when='a'; function='label'; positon='5'; midpoint=motive; x=percent/2; if motive eq 'Dispute' then text=trim(left(put(percent,percent7.0))); else text=trim(left(percent*100)); run; pattern1 color=grayaa; axis1 label=(font="albany amt/bold" height=5 'MOTIVE') value=(justify=right) style=0; axis2 label=none value=none major=none minor=none style=0; title; footnote; proc gchart data=motives anno=motiv_anno; hbar motive / discrete type=sum sumvar=percent nostats descending maxis=axis1 raxis=axis2 noframe coutline=gray55 width=2.7 html=my_html name="motives"; run; /*********** Age of Victim ***********/ proc sql; create table age_vict as select unique barnum, victim_agerange, (count(*)/murder_count) as percent from murderlocs group by victim_agerange; quit; run; proc format; value agefmt 1='<18' 2='18-24' 3='25-40' 4='41-59' 5='60+' ; run; data age_vict; set age_vict; length my_html $300; my_html= 'title='||quote('Age '||trim(left(put(victim_agerange,agefmt.)))|| ': '||trim(left(put(percent,percent7.0))))|| ' href="murder_info.htm"'; run; data anno_age_vict; set age_vict; length style $35 color $12 text $30; xsys='2'; ysys='2'; hsys='3'; when='a'; function='label'; midpoint=barnum; subgroup=victim_agerange; position='4'; style='albany amt'; size=9; if subgroup eq 1 then text=trim(left(put(percent,percent5.0))); else text=trim(left(put(percent*100,comma5.0))); if subgroup in (1,2,3) then color='white'; else color=''; output; ysys='3'; if subgroup in (1,2,4) then y=40; else y=65; color=''; text=trim(left(put(victim_agerange,agefmt.))); output; if _n_=1 then do; style='albany amt/bold'; size=10; text='AGE OF VICTIM'; xsys='3'; ysys='3'; position='6'; x=2; y=65; output; end; run; goptions xpixels=500 ypixels=300; goptions noborder; pattern1 color=gray25; pattern2 color=gray63; pattern3 color=gray96; pattern4 color=graycc; pattern5 color=grayf7; axis1 label=none value=none style=0; axis2 label=none value=none major=none minor=none style=0; proc gchart data=age_vict anno=anno_age_vict; hbar barnum / discrete nostats type=sum sumvar=percent maxis=axis1 raxis=axis2 subgroup=victim_agerange coutline=gray15 width=6 noframe nolegend html=my_html name="age_vict"; run; /*********** Age of Killer ***********/ proc sql; create table age_killer as select unique barnum, killer_agerange, (count(*)/murder_count) as percent from murderlocs group by killer_agerange; quit; run; data age_killer; set age_killer; length my_html $300; my_html= 'title='||quote('Age '||trim(left(put(killer_agerange,agefmt.)))|| ': '||trim(left(put(percent,percent7.0))))|| ' href="murder_info.htm"'; run; data anno_age_killer; set age_killer; length style $35 color $12 text $30; xsys='2'; ysys='2'; hsys='3'; when='a'; function='label'; midpoint=barnum; subgroup=killer_agerange; position='4'; style='albany amt'; size=9; if subgroup eq 1 then text=trim(left(put(percent,percent5.0))); else text=trim(left(put(percent*100,comma5.0))); if subgroup in (1,2,3) then color='white'; else color=''; output; ysys='3'; if subgroup in (1,2,4) then y=40; else y=65; color=''; text=trim(left(put(killer_agerange,agefmt.))); output; if _n_=1 then do; style='albany amt/bold'; size=10; text='AGE OF KILLER*'; xsys='3'; ysys='3'; position='6'; x=2; y=65; output; end; run; goptions xpixels=500 ypixels=300; goptions noborder; pattern1 color=gray25; pattern2 color=gray63; pattern3 color=gray96; pattern4 color=graycc; pattern5 color=grayf7; axis1 label=none value=none style=0; axis2 label=none value=none major=none minor=none style=0; proc gchart data=age_killer anno=anno_age_killer; hbar barnum / discrete nostats type=sum sumvar=percent maxis=axis1 raxis=axis2 subgroup=killer_agerange coutline=gray15 width=6 noframe nolegend html=my_html name="age_kill"; run; /*********** Sex of Victim ***********/ proc sql; create table sex_vict as select unique barnum, victim_sex, (count(*)/murder_count) as percent from murderlocs group by victim_sex; quit; run; proc format; value sexfmt 1='Male' 2='Female' ; run; data sex_vict; set sex_vict; length my_html $300; my_html= 'title='||quote(trim(left(put(victim_sex,sexfmt.)))|| ': '||trim(left(put(percent,percent7.0))))|| ' href="murder_info.htm"'; run; data anno_sex_vict; set sex_vict; length style $35 color $12 text $30; xsys='2'; ysys='2'; hsys='3'; when='a'; function='label'; midpoint=barnum; subgroup=victim_sex; position='4'; style='albany amt'; size=9; if subgroup eq 1 then text=trim(left(put(percent,percent5.0))); else text=trim(left(put(percent*100,comma5.0))); if subgroup eq 1 then color='white'; else color=''; output; ysys='3'; if subgroup eq 1 then y=40; else y=65; color=''; text=trim(left(put(victim_sex,sexfmt.))); output; if _n_=1 then do; style='albany amt/bold'; size=10; text='SEX OF VICTIM'; xsys='3'; ysys='3'; position='6'; x=2; y=65; output; end; run; goptions xpixels=500 ypixels=300; goptions noborder; pattern1 color=gray96; pattern2 color=graycc; axis1 label=none value=none style=0; axis2 label=none value=none major=none minor=none style=0; proc gchart data=sex_vict anno=anno_sex_vict; hbar barnum / discrete nostats type=sum sumvar=percent maxis=axis1 raxis=axis2 subgroup=victim_sex coutline=gray15 width=6 noframe nolegend html=my_html name="sex_vict"; run; /*********** Sex of Killer ***********/ proc sql; create table sex_kill as select unique barnum, killer_sex, (count(*)/murder_count) as percent from murderlocs group by killer_sex; quit; run; proc format; value sexfmt 1='Male' 2='Female' ; run; data sex_kill; set sex_kill; length my_html $300; my_html= 'title='||quote(trim(left(put(killer_sex,sexfmt.)))|| ': '||trim(left(put(percent,percent7.0))))|| ' href="murder_info.htm"'; run; data anno_sex_kill; set sex_kill; length style $35 color $12 text $30; xsys='2'; ysys='2'; hsys='3'; when='a'; function='label'; midpoint=barnum; subgroup=killer_sex; position='4'; style='albany amt'; size=9; if subgroup eq 1 then text=trim(left(put(percent,percent5.0))); else text=trim(left(put(percent*100,comma5.0))); if subgroup eq 1 then color='white'; else color=''; output; ysys='3'; if subgroup eq 1 then y=40; else y=65; color=''; text=trim(left(put(killer_sex,sexfmt.))); output; style='albany amt/bold'; size=10; text='SEX OF KILLER'; xsys='3'; ysys='3'; position='6'; x=2; y=65; output; run; goptions xpixels=500 ypixels=300; goptions noborder; pattern1 color=gray96; pattern2 color=graycc; axis1 label=none value=none style=0; axis2 label=none value=none major=none minor=none style=0; proc gchart data=sex_kill anno=anno_sex_kill; hbar barnum / discrete nostats type=sum sumvar=percent maxis=axis1 raxis=axis2 subgroup=killer_sex coutline=gray15 width=6 noframe nolegend html=my_html name="sex_kill"; run; /*********** Race of Victim ***********/ proc sql; create table race_vict as select unique barnum, victim_race, (count(*)/murder_count) as percent from murderlocs group by victim_race; quit; run; proc format; value racefmt 1='Black' 2='Hispanic' 3='White' 4='Asian' ; run; data race_vict; set race_vict; length my_html $300; my_html= 'title='||quote(trim(left(put(victim_race,racefmt.)))|| ': '||trim(left(put(percent,percent7.0))))|| ' href="murder_info.htm"'; run; data anno_race_vict; set race_vict; length style $35 color $12 text $30; xsys='2'; ysys='2'; hsys='3'; when='a'; function='label'; midpoint=barnum; subgroup=victim_race; position='4'; style='albany amt'; size=9; if subgroup eq 1 then text=trim(left(put(percent,percent5.0))); else text=trim(left(put(percent*100,comma5.0))); if subgroup in (1,2) then color='white'; else color=''; output; ysys='3'; if subgroup in (1,3) then y=40; else y=65; color=''; text=trim(left(put(victim_race,racefmt.))); output; if _n_=1 then do; style='albany amt/bold'; size=10; text='RACE OF VICTIM'; xsys='3'; ysys='3'; position='6'; x=2; y=65; output; end; run; goptions xpixels=500 ypixels=300; goptions noborder; pattern1 color=gray63; pattern2 color=gray96; pattern3 color=graycc; pattern4 color=grayf7; axis1 label=none value=none style=0; axis2 label=none value=none major=none minor=none style=0; proc gchart data=race_vict anno=anno_race_vict; hbar barnum / discrete nostats type=sum sumvar=percent maxis=axis1 raxis=axis2 subgroup=victim_race coutline=gray15 width=6 noframe nolegend html=my_html name="racevict"; run; /*********** Race of Killer ***********/ proc sql; create table race_kill as select unique barnum, killer_race, (count(*)/murder_count) as percent from murderlocs group by killer_race; quit; run; proc format; value racefmt 1='Black' 2='Hispanic' 3='White' 4='Asian' ; run; data race_kill; set race_kill; length my_html $300; my_html= 'title='||quote(trim(left(put(killer_race,racefmt.)))|| ': '||trim(left(put(percent,percent7.0))))|| ' href="murder_info.htm"'; run; data anno_race_kill; set race_kill; length style $35 color $12 text $30; xsys='2'; ysys='2'; hsys='3'; when='a'; function='label'; midpoint=barnum; subgroup=killer_race; position='4'; style='albany amt'; size=9; if subgroup eq 1 then text=trim(left(put(percent,percent5.0))); else text=trim(left(put(percent*100,comma5.0))); if subgroup in (1,2) then color='white'; else color=''; output; ysys='3'; if subgroup in (1,3) then y=40; else y=65; color=''; text=trim(left(put(killer_race,racefmt.))); output; if _n_=1 then do; style='albany amt/bold'; size=10; text='RACE OF KILLER'; xsys='3'; ysys='3'; position='6'; x=2; y=65; output; end; run; goptions xpixels=500 ypixels=300; goptions noborder; pattern1 color=gray63; pattern2 color=gray96; pattern3 color=graycc; pattern4 color=grayf7; axis1 label=none value=none style=0; axis2 label=none value=none major=none minor=none style=0; proc gchart data=race_kill anno=anno_race_kill; hbar barnum / discrete nostats type=sum sumvar=percent maxis=axis1 raxis=axis2 subgroup=killer_race coutline=gray15 width=6 noframe nolegend html=my_html name="racekill"; run; /*********** Victim's Relationship to Killer ***********/ proc sql; create table relation as select unique barnum, vict_rel, (count(*)/murder_count) as percent from murderlocs group by vict_rel; quit; run; proc format; value relfmt 1='Friend' 2='Stranger' 3='Relative' 4='Other' ; run; data relation; set relation; length my_html $300; my_html= 'title='||quote(trim(left(put(vict_rel,relfmt.)))|| ': '||trim(left(put(percent,percent7.0))))|| ' href="murder_info.htm"'; run; data anno_relation; set relation; length style $35 color $12 text $30; xsys='2'; ysys='2'; hsys='3'; when='a'; function='label'; midpoint=barnum; subgroup=vict_rel; position='4'; style='albany amt'; size=9; if subgroup eq 1 then text=trim(left(put(percent,percent5.0))); else text=trim(left(put(percent*100,comma5.0))); if subgroup in (1,2) then color='white'; else color=''; output; ysys='3'; if subgroup in (1,3) then y=40; else y=65; color=''; text=trim(left(put(vict_rel,relfmt.))); output; if _n_=1 then do; style='albany amt/bold'; size=10; xsys='3'; ysys='3'; position='6'; x=2; y=75; text="VICTIM'S RELATIONSHIP"; output; y=65; text='TO KILLER'; output; end; run; goptions xpixels=500 ypixels=300; goptions noborder; pattern1 color=gray63; pattern2 color=gray96; pattern3 color=graycc; pattern4 color=grayf7; axis1 label=none value=none style=0; axis2 label=none value=none major=none minor=none style=0; proc gchart data=relation anno=anno_relation; hbar barnum / discrete nostats type=sum sumvar=percent maxis=axis1 raxis=axis2 subgroup=vict_rel coutline=gray15 width=6 noframe nolegend html=my_html name="relation"; run; /*********** Location of Murder ***********/ proc sql; create table location as select unique barnum, murd_loc, (count(*)/murder_count) as percent from murderlocs group by murd_loc; quit; run; proc format; value locfmt 1='Brooklyn' 2='Bronx' 3='Queens' 4='Manhattan' 5='Staten-Is' ; run; data location; set location; length my_html $300; my_html= 'title='||quote(trim(left(put(murd_loc,locfmt.)))|| ': '||trim(left(put(percent,percent7.0))))|| ' href="murder_info.htm"'; run; data anno_location; set location; length style $35 color $12 text $30; xsys='2'; ysys='2'; hsys='3'; when='a'; function='label'; midpoint=barnum; subgroup=murd_loc; position='4'; style='albany amt'; size=9; if subgroup eq 1 then text=trim(left(put(percent,percent5.0))); else text=trim(left(put(percent*100,comma5.0))); if subgroup in (1,2,3) then color='white'; else color=''; output; ysys='3'; if subgroup in (1,3,5) then y=40; else y=65; color=''; text=trim(left(put(murd_loc,locfmt.))); output; if _n_=1 then do; style='albany amt/bold'; size=10; xsys='3'; ysys='3'; position='6'; x=2; y=65; text='LOCATION'; output; end; run; goptions xpixels=500 ypixels=300; goptions noborder; pattern1 color=gray25; pattern2 color=gray63; pattern3 color=gray96; pattern4 color=graycc; pattern5 color=grayf7; axis1 label=none value=none style=0; axis2 label=none value=none major=none minor=none style=0; proc gchart data=location anno=anno_location; hbar barnum / discrete nostats type=sum sumvar=percent maxis=axis1 raxis=axis2 subgroup=murd_loc coutline=gray15 width=6 noframe nolegend html=my_html name="location"; run; /*********** Weapon used in Murder ***********/ proc sql; create table weapon as select unique barnum, murd_wep, (count(*)/murder_count) as percent from murderlocs group by murd_wep; quit; run; proc format; value wepfmt 1='Firearm' 2='Cutting' 3='Blunt Instrument' 4='Other' ; run; data weapon; set weapon; length my_html $300; my_html= 'title='||quote(trim(left(put(murd_wep,wepfmt.)))|| ': '||trim(left(put(percent,percent7.0))))|| ' href="murder_info.htm"'; run; data anno_weapon; set weapon; length style $35 color $12 text $30; xsys='2'; ysys='2'; hsys='3'; when='a'; function='label'; midpoint=barnum; subgroup=murd_wep; position='4'; style='albany amt'; size=9; if subgroup eq 1 then text=trim(left(put(percent,percent5.0))); else text=trim(left(put(percent*100,comma5.0))); if subgroup in (1,2) then color='white'; else color=''; output; ysys='3'; if subgroup in (1,2,4) then y=40; else y=65; color=''; text=trim(left(put(murd_wep,wepfmt.))); output; if _n_=1 then do; style='albany amt/bold'; size=10; xsys='3'; ysys='3'; position='6'; x=2; y=65; text='WEAPON'; output; end; run; goptions xpixels=500 ypixels=300; goptions noborder; pattern1 color=gray63; pattern2 color=gray96; pattern3 color=graycc; pattern4 color=grayf7; axis1 label=none value=none style=0; axis2 label=none value=none major=none minor=none style=0; proc gchart data=weapon anno=anno_weapon; hbar barnum / discrete nostats type=sum sumvar=percent maxis=axis1 raxis=axis2 subgroup=murd_wep coutline=gray15 width=6 noframe nolegend html=my_html name="weapon"; run; /*********** NYC Race Distribution ***********/ data race_nyc; input race percent; barnum=1; datalines; 1 .25 2 .28 3 .35 4 .11 ; run; proc format; value racefmt 1='Black' 2='Hispanic' 3='White' 4='Asian' ; run; data race_nyc; set race_nyc; length my_html $300; my_html= 'title='||quote(trim(left(put(race,racefmt.)))|| ': '||trim(left(put(percent,percent7.0))))|| ' href="murder_info.htm"'; run; data anno_race_nyc; set race_nyc; length style $35 color $12 text $30; xsys='2'; ysys='2'; hsys='3'; when='a'; function='label'; midpoint=barnum; subgroup=race; position='4'; style='albany amt'; size=9; if subgroup eq 1 then text=trim(left(put(percent,percent5.0))); else text=trim(left(put(percent*100,comma5.0))); if subgroup in (1,2) then color='white'; else color=''; output; ysys='3'; if subgroup in (1,3) then y=40; else y=65; color=''; text=trim(left(put(race,racefmt.))); output; if _n_=1 then do; style='albany amt/bold'; size=10; xsys='3'; ysys='3'; position='6'; x=2; y=75; text='OVERALL'; output; y=65; text='RACE OF NYC'; output; end; run; goptions xpixels=500 ypixels=300; goptions noborder; pattern1 color=gray63; pattern2 color=gray96; pattern3 color=graycc; pattern4 color=grayf7; axis1 label=none value=none style=0; axis2 label=none value=none major=none minor=none style=0; proc gchart data=race_nyc anno=anno_race_nyc; hbar barnum / discrete nostats type=sum sumvar=percent maxis=axis1 raxis=axis2 subgroup=race coutline=gray15 width=6 noframe nolegend html=my_html name="race_nyc"; run; goptions display; goptions border; goptions xpixels=1400 ypixels=700; goptions cback=cxFFFFE0; ODS LISTING CLOSE; ODS HTML path=odsout body="&name..htm" (title="NYC Crime Dashboard") style=htmlblue; proc greplay tc=tempcat nofs igout=work.gseg; tdef murder des='Murder' 0/llx = 0 lly = 0 ulx = 0 uly =100 urx = 70 ury =100 lrx = 70 lry = 0 1/llx =47 lly = 2 ulx =47 uly = 95 urx =100 ury = 95 lrx =100 lry = 2 2/llx =34 lly = 0 ulx =34 uly = 45 urx =46 ury = 45 lrx =46 lry = 0 3/llx = 1 lly = 67 ulx = 1 uly = 87 urx =23 ury = 87 lrx =23 lry = 67 4/llx =26 lly = 67 ulx =26 uly = 87 urx =48 ury = 87 lrx =48 lry = 67 5/llx = 1 lly = 57 ulx = 1 uly = 77 urx =23 ury = 77 lrx =23 lry = 57 6/llx =26 lly = 57 ulx =26 uly = 77 urx =48 ury = 77 lrx =48 lry = 57 7/llx = 1 lly = 47 ulx = 1 uly = 67 urx =23 ury = 67 lrx =23 lry = 47 8/llx =26 lly = 47 ulx =26 uly = 67 urx =48 ury = 67 lrx =48 lry = 47 9/llx =14 lly = 34 ulx =14 uly = 54 urx =36 ury = 54 lrx =36 lry = 34 10/llx = 1 lly = 22 ulx = 1 uly = 42 urx =23 ury = 42 lrx =23 lry = 22 11/llx = 1 lly = 12 ulx = 1 uly = 32 urx =23 ury = 32 lrx =23 lry = 12 12/llx = 1 lly = 2 ulx = 1 uly = 22 urx =23 ury = 22 lrx =23 lry = 2 ; template = murder; treplay 0:titles 1:mainmap 3:age_vict 4:age_kill 5:sex_vict 6:sex_kill 7:racevict 8:racekill 9:race_nyc 10:relation 11:location 12:weapon 2:motives des='' name="&name"; run; quit; ODS HTML CLOSE; ODS LISTING;