Skip to content. | Skip to navigation

Personal tools

DQI-Revised SAS program for age 18 and older

** DQI_R18+.SAS **;
** This program was originally called 'csf9634'  **;

** The following is an attempt to explain data set names and
 variable names used in this program. 

csf9602.ssd01 is the SAS data set of rt32.dat 
       (food item-level pyramid food group servings, ages 2 and up)
          sorted by hhid personid daycode seqnum.

The variable 'spnum' was renamed to 'personid'.
The variable 'dayct' is a created variable that is equal to 
 the number of days a subject reported eating food.  People who 
 fasted have a dayct equal to 1 despite the fact they reported two
 days of intake (comp_d1 and comp_d2 both equal to 1).
The variables 'eatday1' and 'eatday2' are created variables:
 eatday1=(d1_nrec>0);
 eatday2=(d2_nrec>0);

csf9603.ssd01 is the SAS data set of rt42.dat where each person has
        only 1 observation instead of 2 or 3 observations.
       (individual-level data, pyramid food group serving day1 totals, ages 2 and up)
          sorted by hhid personid

The following is documentation of the renamed variables for day1 totals:
         G_TOTAL  = grains1
         G_WHL    = grainsw1
         G_NWHL   = grainsn1
         V_TOTAL  = veges1
         V_DRKGR  = vegesdg1
         V_DPYEL  = vegesdy1
         V_LEGUME = vegesl1
         V_POTATO = vegesp1
         V_STARCY = vegess1
         V_TOMATO = vegest1
         V_OTHER  = vegeso1
         F_TOTAL  = fruit1
         F_CITMLB = fruitc1
         F_OTHER  = fruito1
         D_TOTAL  = dairy1
         D_MILK   = dairym1
         D_YOGURT = dairyy1
         D_CHEESE = dairyc1
         M_MPF    = meatpf1
         M_MEAT   = meatbp1
         M_ORGAN  = meato1
         M_FRANK  = meatfl1
         M_POULT  = meatp1
         M_FISH   = meatf1
         M_EGG    = meate1
         M_SOY    = meats1
         M_NUTSD  = meatns1
         DISCFAT  = dfat1
         ADD_SUG  = asugar1
         A_BEV    = alcnum1
         ENERGY   = kcal1
         TFAT     = fat1
         
The 2-day average variables are the same except they end with '2' instead
of '1'.

csf9633.ssd01 is the SAS data set of rt40.dat where each person has
        only 1 observation instead of 2 or 3 observations.
        It contains day 1 and 2-day average variables.

The following is documentation of the renamed variables for day1 totals:
   SODIUM   =   sodium1 
   CALCIUM  =   calc1 
   VITA_R   =   vare1 
   VITE     =	ve1 
   VITC     =   vc1 
   FOLATE   =   fola1 
   ZINC     =   zinc1  
   SFAT	    =   satf1  
   CHOLES   =   chol1
   R_IRON   =   rdairon1

The 2-day average variables are the same except they end with '2' instead
of '1'.

foodcode.asc is an ASCII file that is a slightly modified
 version of foodcode.txt.  I made the file a delimited file with 
 the carrot (^) symbol to make it easier to read into SAS.
 The file foodcode.txt could be read in by some other manner
 and be used instead.
 
******************************************************************;


***********************************************************************
Program: csf9634                            Stream: /usda/csf96
Input: /csf96/data/csf9602                  Output: csf9634 
       /csf96/data/csf9603   
       /csf96/data/csf9633
       /docs/foodcode.asc

Programmer: Dan Blanchette            Date: 11Dec1997
Last run:   Dan Blanchette            Date: 24Jun1998

* Create DQI-Revised.                                                 *
* Create Diet Variety Scores from food level file.                    *
  Create Moderation Scores from Day total and 2-Day average file.
*        Ages 18 and over                                             *
*                                                                     *
*      There are 5 day1 fasters and 8 day2 fasters making 13 total    *
*       (the missing 2 are under 18) The 8 day2 fasters will have     *
*       day1 totals and 2-day avgs (both the same value).  The 5      *
*       day1 fasters will have no day1 total but will have a 2-day    *
*       average. "where dayct=1 and comp_d1=1 and comp_d2=1 selects   *
*       the fasters.                                                  *
*                                                                     *
* Search foodcode descriptions for food group words to assist         *
*  in food grouping of grains servings.                               *
*                                                                     *
***********************************************************************;
%let root=/usda/csf96;
%let job=/progs/csf9634;
%let land=ps=65 ls=240 nocenter;
%let land1=ps=65 ls=175 nocenter;
%let por=ps=65 ls=86 center;

options &por;
libname data "&root/data";

title1 "1994-96 CSFII Stream: Diet Variety Score ";
title2 "Ages 18 and over";
footnote "program &root.&job"; 

filename in "&root/docs/foodcode.asc";

*** create data set for description of foodcodes for keyword search **;
data fooddesc;
  infile in dlm='^';
length foodcode 8 fooddesc $ 60;
 input @1 foodcode fooddesc;

label
 foodcode='Food code'
 fooddesc='8-digit, 60 char food description';

run;

proc format;
value 
 grainnum
   1="1=GRAIN"
   3="3=PASTA"
   4="4=RICE"
   5="5=CEREAL" 
   7="7=QK BREAD"
;;;;
** The following is an expanded version of the same format.
 grainnum
   1="1=WHOLE GRAIN BREADS, ROLLS, CRACKERS, ETHNIC MIXTURES"
   2="2=NON-WHOLE GRAIN BREADS, ROLLS, CRACKERS, ETHNIC MIXTURES"
   3="3=PASTA"
   4="4=RICE"
   5="5=WHOLE GRAIN CEREALS" 
   6="6=NON-WHOLE GRAIN CEREALS" 
   7="7=QUICK BREADS"
;;;;
run;

data found2 notfound fooddesc;
 set fooddesc;

graingrp=0; *** sets food group var  ***; 

*** Search for keywords in food description to assign the appropriate value to graingrp.*** ;
%MACRO SEARCH(word,fdgrpno);
**** if index(fooddesc,"RICE") then graingrp=1;
if index(fooddesc,upcase("&word")) then graingrp=&fdgrpno;

%MEND;
/* Grains */
%SEARCH(english muffin,1)
%SEARCH(chimichanga,1)
%SEARCH(quesadilla,1)
%SEARCH(nacho,1)
%SEARCH(egg roll,1)
%SEARCH(croissant,1)
%SEARCH(pot pie,1)     
%SEARCH(BURRITO,1)     
%SEARCH(TACO,1)     
%SEARCH(enchilada,1)     
%SEARCH(PIZZA,1)     
%SEARCH(BUN,1)
%SEARCH(fajita,1)
%SEARCH(tortilla,1)
%SEARCH(SAND,1)
%SEARCH(DUMPL,1)
%SEARCH(STUFFI,1)

/* Pasta */
%SEARCH(rigaton,3)
%SEARCH(NOOD,3)
%SEARCH(tetrazzin,3)
%SEARCH(MACARON,3) 
%SEARCH(lo mein,3) 
%SEARCH(gnocch,3) 
%SEARCH(cannellon,3) 
%SEARCH(TORTEL,3)  
%SEARCH(manicott,3)     
%SEARCH(linguin,3)     
%SEARCH(fettuccin,3)     
%SEARCH(spaghetti,3)
%SEARCH(stuffed shell,3)
%SEARCH(mosticolli,3)
%SEARCH(pasta,3)
%SEARCH(raviol,3)
%SEARCH(lasagna,3)

/* Rice */
%SEARCH(sushi,4)
%SEARCH(RICE,4)
%SEARCH(paella,4)
%SEARCH(stuffed pepper,4)

/*Quick Breads*/
%SEARCH(biscuit,7)

if graingrp>0 then output found2;
else if graingrp=0 and (58000000<=foodcode<59000000) then output notfound;
else output fooddesc;

format graingrp grainnum.; 
label 
 graingrp = "Grain Group assignment for DVS"
;;;
run;

data fooddesc found1;
 set fooddesc;

graingrp=0; *** sets food group var  ***; 

**Grain;
if foodcode in(
27246300,
27250030,
27250040,
27250050,
27250070,
27250160,
27250210,
27250300,
27513040,
27515000,
27515020,
27515070,
27520170,
27520250,
27520380,
27520390,
27520500,
27550750,
27560300,
27560350,
27560650,
27560670,
27570310) or 
foodcode in(58120110,58120120) 
then graingrp=1;  

**Pasta; 
if 56100000<=foodcode<56200000 then graingrp=3;

**Rice;
if foodcode in(27213120,27213420) then graingrp=4;

**Crackers;
if 54000000<=foodcode<55000000 then graingrp=1;

**Cereal;
if 56200000<=foodcode<56204000 
or 56206000<=foodcode<56300000 
or 57000000<=foodcode<58000000 then graingrp=5;

**Quick Breads;
if 52000000<=foodcode<53000000 or 54000000<=foodcode<55000000 then graingrp=7;

** fix bad matches (this may no longer be needed**;
***Grains;
if
(51000000<=foodcode<52000000) or
(58101200<=foodcode<=58117510) or
(58122250<=foodcode<=58127150) or
(58128210<=foodcode<=58128250) or
foodcode in(58175110,58310310,58401010,58401200,58404500) then graingrp=1;

**Pasta;
if foodcode in(58122210,58408010) then graingrp=3;

if graingrp>0 then output found1;
else output fooddesc;
run;

** concatenate data sets;
data fooddesc;
 set found1 found2; by foodcode;

** weed out bad matches  **;
if index(fooddesc,upcase("licorice"))
 or index(fooddesc,upcase("no rice"))
 or index(fooddesc,upcase("no noodles"))
 or index(fooddesc,upcase("spaghetti sauce"))
 or index(fooddesc,upcase("enchilada sauce"))
 or index(fooddesc,upcase("squash, spaghetti"))
 or index(fooddesc,upcase("pizza cheese"))
 or index(fooddesc,upcase("pizza mate"))
 or index(fooddesc,upcase("sandwich loaf"))
 or index(fooddesc,upcase("sandwich spread"))
 or index(fooddesc,upcase("thousand"))
 or index(fooddesc,upcase("cookie"))
 or foodcode in(58118110,58118210,58149210,58156610,58310110,58400000,58407000,58407020,58407070,58421000)  
 or foodcode<14000000 
 or foodcode>90000000 
 then graingrp=0;

** assure that any cereal is a cereal, eg. rice krispies cereal not "rice";
 if index(fooddesc,upcase("cereal")) then graingrp=5;
run;

proc sort data=data.csf9602 
         (keep=hhid     personid daycode  foodcode age dayct eatday1 eatday2
               g_total  g_whl    g_nwhl 
               v_drkgr  v_dpyel  v_legume v_potato v_starcy v_tomato v_other
               d_milk   d_yogurt d_cheese 
               m_meat   m_organ  m_frank  m_poult  m_fish m_egg m_soy
               f_citmlb f_other  wta_day1  wta_2day wt3_day1 wt3_2day year)
 out=csf9602;
  by foodcode;
  where age>=18;
run;

data csf9602;
merge csf9602(in=a) fooddesc(in=b); by foodcode;
if a=1 then output csf9602; ** only want foods consumed in 1994-96 **;
run;

proc sort data=csf9602; by hhid personid daycode foodcode;
run;

/*
*Sample output;
options &land;
proc print data=csf9602 (obs=100);
title3 "1st 100 obs of csf9602";
run;
*/

** Create diet variety scores.  Add up day totals. ***;
data csf9634 (drop=i foodcode daycode graingrp
               g_total  g_whl    g_nwhl 
               v_drkgr  v_dpyel  v_legume v_potato v_starcy v_tomato v_other
               d_milk   d_yogurt d_cheese 
               m_meat   m_organ  m_frank  m_poult m_fish m_egg m_soy
               f_citmlb f_other
               v_legsoy m_meorfr d_milkyo
               fcamt1-fcamt22);
 set csf9602 (drop=fooddesc); by hhid personid daycode foodcode;
 retain d1dvg1  d1dvg2  d1dvg3  d1dvg4  d1dvg5  d1dvg6  d1dvg7   /*Grains*/
        d2dvg1  d2dvg2  d2dvg3  d2dvg4  d2dvg5  d2dvg6  d2dvg7 
        d1dvv1  d1dvv2  d1dvv3  d1dvv4  d1dvv5  d1dvv6  d1dvv7   /*Veges*/
        d2dvv1  d2dvv2  d2dvv3  d2dvv4  d2dvv5  d2dvv6  d2dvv7 
        d1dvdm1 d1dvdm2 d1dvdm3 d1dvdm4 d1dvdm5 d1dvdm6   /*Dairy & Meat*/
        d2dvdm1 d2dvdm2 d2dvdm3 d2dvdm4 d2dvdm5 d2dvdm6  
        d1dvf1  d1dvf2                                           /*Fruit*/
        d2dvf1  d2dvf2 
        fcamt1-fcamt22;

**Combine legumes and soy servings per foodcode;
v_legsoy=sum(v_legume,m_soy);

**Combine meat, organ, and frank servings per foodcode;
m_meorfr=sum(m_meat,m_organ,m_frank);

**Combine Milk and Yogurt;
d_milkyo=sum(d_milk,d_yogurt);

 array vege  (7) v_drkgr  v_dpyel  v_legsoy v_potato v_starcy  v_tomato v_other; ** Vegetables;
 array dame  (6) d_milkyo d_cheese m_meorfr m_poult   m_fish   m_egg;            ** Dairy & Meats;
 array fruit (2) f_citmlb f_other;                                               ** Fruit;

 array dvgrnd1  (7) d1dvg1  d1dvg2  d1dvg3  d1dvg4  d1dvg5  d1dvg6  d1dvg7;  ** day1;
 array dvgrnd2  (7) d2dvg1  d2dvg2  d2dvg3  d2dvg4  d2dvg5  d2dvg6  d2dvg7;  ** 2-day;
 array dvveged1 (7) d1dvv1  d1dvv2  d1dvv3  d1dvv4  d1dvv5  d1dvv6  d1dvv7;
 array dvveged2 (7) d2dvv1  d2dvv2  d2dvv3  d2dvv4  d2dvv5  d2dvv6  d2dvv7;
 array dvdamed1 (6) d1dvdm1 d1dvdm2 d1dvdm3 d1dvdm4 d1dvdm5 d1dvdm6;
 array dvdamed2 (6) d2dvdm1 d2dvdm2 d2dvdm3 d2dvdm4 d2dvdm5 d2dvdm6;
 array dvfrutd1 (2) d1dvf1  d1dvf2;
 array dvfrutd2 (2) d2dvf1  d2dvf2;

 array fcamnt (22) fcamt1-fcamt22;
 array serving (22) g_whl    g_nwhl   g_total  g_total  g_whl    g_nwhl   g_total
                    v_drkgr  v_dpyel  v_legsoy v_potato v_starcy v_tomato v_other
                    d_milkyo d_cheese m_meorfr m_poult  m_fish   m_egg
                    f_citmlb f_other;

*Sum up servings of the same foodcodes eaten in the same day;
if first.foodcode then do i=1 to 22;
  fcamnt(i)=0;  ** resets for each change in foodcode or change in day, person, etc.;
end;

 do i=1 to 22;
  fcamnt(i)=serving(i)+fcamnt(i);  *sum up servings of same foodcode;
 end;
 if last.foodcode then do i=1 to 22;
  serving(i)=fcamnt(i);  ** resets the value of the serving vars to foodcode total number of servings;
 end;

%MACRO Day(dy); *creates Day1 and Day2 totals.  2-Day avg needs to be computed; 
 if first.personid then do i=1 to 7;
   if (i<=7) then dvgrnd&dy(i)=0;   ** re-sets to initial values  **;
   if (i<=7) then dvveged&dy(i)=0;             
   if (i<=6) then dvdamed&dy(i)=0;
   if (i<=2) then dvfrutd&dy(i)=0;
 end;

if last.foodcode then do;

 ** For Day1 and Day2 totals: **;
 ** Create dummy vars (=0 or =1) for each food group: if .5<g_whl then var=1, else var=0 **;
  
 ***Grains;

  **Grains and Cereals: graingrp in(1,2,5,6);
   if graingrp in(1,5) then do;
   if dvgrnd&dy(graingrp)=0 then 
      dvgrnd&dy(graingrp)=(.5<=g_whl); ** =0 or if more than 1/2 serving =1 **; 

   if dvgrnd&dy(graingrp+1)=0 then 
    dvgrnd&dy(graingrp+1)=(.5<=g_nwhl);  ** graingrp in(2,6) are non-whole grain;
   end; ** of graingrp in(1,5) do loop;

  **Pasta,Rice,Quick Breads: graingrp in(3,4,7);
   if graingrp in(3,4,7) then do;
   if dvgrnd&dy(graingrp)=0 then 
      dvgrnd&dy(graingrp)=(.5<=g_total); ** if more than 1/2 serving =1 **; 
   end; ** end of graingrp in(3,4,7) do loop;

 ***Veges;
  do i=1 to 7;
  if dvveged&dy(i)=0 then
     dvveged&dy(i)=(.5<=vege(i)); ** if at least 1/2 serving then make it =1 **; 
  end;         

 ***Meat & Dairy;
  do i=1 to 6;
  if dvdamed&dy(i)=0 then
     dvdamed&dy(i)=(.5<=dame(i)); ** if at least 1/2 serving then make it =1 **; 
  end;

 ***Fruit;
  do i=1 to 2;
  if dvfrutd&dy(i)=0 then
     dvfrutd&dy(i)=(.5<=fruit(i)); ** if at least 1/2 serving then make it =1 **; 
  end;

end; ** of last.foodcode do loop;

%MEND;  ** end of Day macro;

%Day(1)
%Day(2)

if last.personid then do;
 
** Create 2-Day Average Dummy vars from Day1 and Day2 totals **;
    do i=1 to 7;
   *** if true then it's equal to 1 else equal to 0  ***; 
if (i<=7) then dvgrnd2(i) =(1<=sum(dvgrnd1(i) ,dvgrnd2(i)));   ** if 1 either day then avg =1;
if (i<=7) then dvveged2(i)=(1<=sum(dvveged1(i),dvveged2(i)));  ** if 1 either day then avg =1;
if (i<=6) then dvdamed2(i)=(1<=sum(dvdamed1(i),dvdamed2(i)));  ** if 1 either day then avg =1;
if (i<=2) then dvfrutd2(i)=(1<=sum(dvfrutd1(i),dvfrutd2(i)));  ** if 1 either day then avg =1;
 end;
* else if dayct=1 then do i=1 to 7;  ** if did not eat both days should not have 2-day average;
* if (i<=7) then dvgrnd2(i) =.;
* if (i<=7) then dvveged2(i)=.;  **** commented out so that a day1 total could be a 2-day average **;
* if (i<=6) then dvdamed2(i)=.;  **** for people with no day2 total  **;
* if (i<=2) then dvfrutd2(i)=.;
* end;
 if eatday1=0 then do i=1 to 7;  ** did not eat day1 should not have day1 totals;
if (i<=7) then dvgrnd1(i) =.;
if (i<=7) then dvveged1(i)=.;
if (i<=6) then dvdamed1(i)=.;
if (i<=2) then dvfrutd1(i)=.;
end;

** sum across each array to create diet variety total scores **;
    d1dvsg=0;  ** initialize vars to add up diversity food group vars day 1 and 2-day ***;
    d1dvsv=0;
    d1dvsdm=0;
    d1dvsf=0;

    d2dvsg=0;
    d2dvsv=0;
    d2dvsdm=0;
    d2dvsf=0;

   do i=1 to 7;
          *** the sum function is used so that missings are not kept missing ;
    if (i<=7) then d1dvsg=sum(d1dvsg,dvgrnd1(i)); 
    if (i<=7) then d1dvsv=sum(d1dvsv,dvveged1(i));
    if (i<=6) then d1dvsdm=sum(d1dvsdm,dvdamed1(i));
    if (i<=2) then d1dvsf=sum(d1dvsf,dvfrutd1(i));

    if (i<=7) then d2dvsg=sum(d2dvsg,dvgrnd2(i));
    if (i<=7) then d2dvsv=sum(d2dvsv,dvveged2(i));
    if (i<=6) then d2dvsdm=sum(d2dvsdm,dvdamed2(i));
    if (i<=2) then d2dvsf=sum(d2dvsf,dvfrutd2(i));
   end;

if eatday1=0 then do; ** did not eat on day1 should not have day1 total;
    d1dvsg=.;
    d1dvsv=.;
    d1dvsdm=.;
    d1dvsf=.;
end;
**if dayct=1 then do;  ** did not eat both days should not have 2-day average;
  *  d2dvsg=.;
  *  d2dvsv=.;
  *  d2dvsdm=.;
  *  d2dvsf=.;
* end;

*Create Diet Variety Score;
    d1dvs=d1dvsg
         +d1dvsv
         +d1dvsdm
         +d1dvsf;
    d2dvs=sum(d2dvsg,
              d2dvsv,
              d2dvsdm,
              d2dvsf);  

 ** Create Diet Variety Score as a 10pt score **;
  * (the denominator is the number of components of that scores subgroup);  
    d1dvswtd=2.5*(d1dvsg/7)
            +2.5*(d1dvsv/7)
            +2.5*(d1dvsdm/6)
            +2.5*(d1dvsf/2);  
    d2dvswtd=2.5*(d2dvsg/7)
            +2.5*(d2dvsv/7)
            +2.5*(d2dvsdm/6)
            +2.5*(d2dvsf/2);  

  output;  *** outputs only one obs per person  ***;
end; ** of if last.personid do loop;

label  
   d1dvs     = "Day1 Tot Diet Variety Score (DVS)"
   d2dvs     = "2-Day Avg Diet Variety Score (DVS)"
   d1dvswtd  = "Day1 Tot Diet Variety Scr(DVS),weighted"
   d2dvswtd  = "2-Day Avg Diet Variety Scr(DVS),weighted"
   d1dvsg    = "Day1 Tot Diet Variety Score (DVS)-Grain"
   d1dvsv    = "Day1 Tot Diet Variety Score (DVS)-Veges"
   d1dvsdm   = 'Day1 Tot Diet Varty Scr (DVS)-Dairy&Meat'
   d1dvsf    = "Day1 Tot Diet Variety Score (DVS)-Fruit"
   d2dvsg    = "2-Day Avg Diet Variety Score (DVS)-Grain"
   d2dvsv    = "2-Day Avg Diet Variety Score (DVS)-Veges"
   d2dvsdm   = '2-Day Avg Diet Varty Scr(DVS)-Dairy&Meat'
   d2dvsf    = "2-Day Avg Diet Variety Score (DVS)-Fruit"

  /* Grains */
   d1dvg1 = "Day1 Tot: DV,Breads Whole Serv=>.5" 
   d1dvg2 = "Day1 Tot: DV,Breads Non-Whole Serv=>.5"
   d1dvg3 = "Day1 Tot: DV,Pasta Ser=>.5"
   d1dvg4 = "Day1 Tot: DV,Rice Ser=>.5"
   d1dvg5 = "Day1 Tot: DV,Cereal Whole Serv=&gt.5"
   d1dvg6 = "Day1 Tot: DV,Cereal Non-Whole Serv=&gt.5"
   d1dvg7 = "Day1 Tot: DV,Quick Breads Serv=&gt.5"

   d2dvg1 = "2-Day Avg: DV,Breads Whole Serv=&gt.5"
   d2dvg2 = "2-Day Avg: DV,Breads Non-Whole Serv=&gt.5"
   d2dvg3 = "2-Day Avg: DV,Pasta Ser=&gt.5"
   d2dvg4 = "2-Day Avg: DV,Rice Ser=&gt.5"
   d2dvg5 = "2-Day Avg: DV,Cereal Whole Serv=&gt.5"
   d2dvg6 = "2-Day Avg: DV,Cereal Non-Whole Serv=&gt.5"
   d2dvg7 = "2-Day Avg: DV,Quick Breads Serv=&gt.5"

  /* Veges */
   d1dvv1 = "Day1 Tot: DV,Dark Green Veg. Serv=&gt.5" 
   d1dvv2 = "Day1 Tot: DV,Deep Yellow Veg. Serv=&gt.5" 
   d1dvv3 = "Day1 Tot: DV,Legume/Soy Veg. Serv=&gt.5" 
   d1dvv4 = "Day1 Tot: DV,Potato Veg. Serv=&gt.5" 
   d1dvv5 = "Day1 Tot: DV,Starchy Veg. Serv=&gt.5" 
   d1dvv6 = "Day1 Tot: DV,Tomato Veg. Serv=&gt.5" 
   d1dvv7 = "Day1 Tot: DV,Other Veg. Serv=&gt.5" 
   
   d2dvv1 = "2-Day Avg: DV,Dark Green Veg. Serv=&gt.5" 
   d2dvv2 = "2-Day Avg: DV,Deep Yellow Veg. Serv=&gt.5" 
   d2dvv3 = "2-Day Avg: DV,Legume/Soy Serv=&gt.5" 
   d2dvv4 = "2-Day Avg: DV,Potato Serv=&gt.5" 
   d2dvv5 = "2-Day Avg: DV,Starchy Serv=&gt.5" 
   d2dvv6 = "2-Day Avg: DV,Tomato Serv=&gt.5" 
   d2dvv7 = "2-Day Avg: DV,Other Vegetable Serv=&gt.5" 

  /* Dairy & Meat */
   d1dvdm1 = "Day1 Tot: DV,Milk & Yogurt Serv=&gt.5" 
   d1dvdm2 = "Day1 Tot: DV,Cheese Serv=&gt.5" 
   d1dvdm3 = "Day1 Tot: DV,Meat Organ Frank Serv=&gt.5" 
   d1dvdm4 = "Day1 Tot: DV,Poultry Serv=&gt.5" 
   d1dvdm5 = "Day1 Tot: DV,Fish Serv=&gt.5" 
   d1dvdm6 = "Day1 Tot: DV,Egg Serv=&gt.5" 
   
   d2dvdm1 = "2-Day Avg: DV,Milk & Yogurt Serv=&gt.5" 
   d2dvdm2 = "2-Day Avg: DV,Cheese Serv=&gt.5" 
   d2dvdm3 = "2-Day Avg: DV,Meat Organ Frank Serv=&gt.5" 
   d2dvdm4 = "2-Day Avg: DV,Poultry Serv=&gt.5" 
   d2dvdm5 = "2-Day Avg: DV,Fish Serv=&gt.5" 
   d2dvdm6 = "2-Day Avg: DV,Egg Serv=&gt.5" 

  /* Fruit */
   d1dvf1 = "Day1 Tot: DV,Cit. Mellon Berry Serv=&gt.5" 
   d1dvf2 = "Day1 Tot: DV,Other Fruit Serv=&gt.5" 
   
   d2dvf1 = "2-Day Avg: DV,Cit. Mellon Berry Serv=&gt.5" 
   d2dvf2 = "2-Day Avg: DV,Other Fruit Serv=&gt.5" 
;;; 

run;
/*
*Sample output;
options &land;
proc print data=csf9634 (obs=100);
title3 "1st 100 obs of csf9634";
run;
*/

data csf9634;
 merge data.csf9603(in=a)
            csf9634(in=b) 
       data.csf9633(in=c keep=hhid personid sodium1 sodium2 calc1 calc2
                               vare1 vare2 ve1 ve2 vc1 vc2 fola1 fola2 zinc1 zinc2  
                               satf1 satf2 chol1 chol2 rdairon1 rdairon2 eatday1 eatday2 dayct);
       by hhid personid;
if a=1 and 18<=age;

** create percent ai calcium;
 paicalc1=((calc1/1300)*(14<=age<=18)
          +(calc1/1000)*(19<=age<=50)
          +(calc1/1200)*(51<=age<=99))*100;
 
 paicalc2=((calc2/1300)*(14<=age<=18)
          +(calc2/1000)*(19<=age<=50)
          +(calc2/1200)*(51<=age<=99))*100;

** create ai calcium score;
 aicscr1=round(paicalc1/10,.01); ** round to 100ths;
 if aicscr1&gt10 then aicscr1=10;  ** cap at 10 points;
 aicscr2=round(paicalc2/10,.01);
 if aicscr2&gt10 then aicscr2=10;  

** create percent rda iron and rda iron score;
 rdairon1=rdairon1*100;  ** make rdairon1 a true percent like r_iron is in rt42 **;
 rdairon2=rdairon2*100;  ** make rdairon2 a true percent like r_iron is in rt42 **;
 rdaiscr1=round(rdairon1/10,.01); ** round to 100ths;
  if rdaiscr1&gt10 then rdaiscr1=10;  ** cap at 10pts.;
 rdaiscr2=round(rdairon2/10,.01); 
  if rdaiscr2&gt10 then rdaiscr2=10;

** Create enerfat, enersfat for Day-1 and 2-Day intake **;
     enerfat1=.;
     enersfa1=.;
     enerfat2=.;
     enersfa2=.;
     if kcal1=0 then do;
        enerfat1=0;
        enersfa1=0;
     end;
     else if kcal1&gt0 then do;
        enerfat1=((fat1*9)/kcal1)*100;
        enersfa1=((satf1*9)/kcal1)*100;
     end;
     if kcal2=0 then do;
        enerfat2=0;
        enersfa2=0;
     end;
     else if kcal2&gt0 then do;
        enerfat2=((fat2*9)/kcal2)*100;
        enersfa2=((satf2*9)/kcal2)*100;
     end;

  /* Create categorical variables from continuous vars to be */
  /* use to calculate the DQI;                               */

   if 0<=enerfat1<=30 then efatscr1=10;
      else if 30<enerfat1<=40 then efatscr1=5;
      else if 40<enerfat1 then efatscr1=0;

   if 0<=enersfa1<=10 then esftscr1=10;
      else if 10<enersfa1<=13 then esftscr1=5;
      else if 13<enersfa1 then esftscr1=0;

   if 0<=chol1<=300 then cholscr1=10;
      else if 300<chol1<=400 then cholscr1=5;
      else if 400<chol1 then cholscr1=0;

   if 0<=enerfat2<=30 then efatscr2=10;
      else if 30<enerfat2<=40 then efatscr2=5;
      else if 40<enerfat2 then efatscr2=0;

   if 0<=enersfa2<=10 then esftscr2=10;
      else if 10<enersfa2<=13 then esftscr2=5;
      else if 13<enersfa2 then esftscr2=0;

   if 0<=chol2<=300 then cholscr2=10;
      else if 300<chol2<=400 then cholscr2=5;
      else if 400<chol2 then cholscr2=0;

label
 paicalc1 = 'Day1 Total: AI % Calcium'
 paicalc2 = '2-Day Avg.: AI % Calcium'
 aicscr1  = 'Day1 Total: AI % Calcium 10pt score'
 aicscr2  = '2-Day Avg.: AI % Calcium 10pt score'
 rdaiscr1 = 'Day1 Total: % RDA Iron 10pt score'
 rdaiscr2 = '2-Day Avg.: % RDA Iron 10pt score'
 enerfat1 = 'Day1 Tot: % energy from fat'
 enersfa1 = 'Day1 Tot: % energy from saturated fat'
 efatscr1 = 'Day1 Tot: 10pt Score of enerfat1'
 esftscr1 = 'Day1 Tot: 10pt Score of enersfa1'
 cholscr1 = 'Day1 Tot: cholesterol 10pt score'
 enerfat2 = '2-Day Avg: % energy from fat'
 enersfa2 = '2-Day Avg: % energy from saturated fat'
 efatscr2 = '2-Day Avg: 10pt Score of enerfat2'
 esftscr2 = '2-Day Avg: 10pt Score of enersfa2'
 cholscr2 = '2-Day Avg: cholesterol 10pt score'
;;;
run;

*   Moderation Scores for Alcohol Sodium and Sugar                      * 
*   Ages 18 and over.                                                   *;

data data.csf9634 (drop=count);  ** create permanent dataset;
 set csf9634;
%MACRO dataday(day);

** Add Soy to vege total since legumes and soy are grouped in the Diet Variety Score **;
veges&day=veges&day+meats&day;

%MACRO dqi(kcallo,kcalup,grn_min,frt_min,veg_min,sug_max);

*Grain, Fruit, Veges, and Added Sugar;
if &kcallo<kcal&day<=&kcalup then do;
 *Grains;
  dqigpct&day=(grains&day/&grn_min)*100;
  dqigscr&day=round((grains&day/&grn_min)*10,.01); ** round to 100ths;
  if dqigscr&day&gt10 then dqigscr&day=10;           ** cap at 10 pts.;

 *Vegetables;
  dqivpct&day=(veges&day/&veg_min)*100;
  dqivscr&day=round((veges&day/&veg_min)*10,.01);
  if dqivscr&day&gt10 then dqivscr&day=10;

 *Fruits;
  dqifpct&day=(fruit&day/&frt_min)*100;
  dqifscr&day=round((fruit&day/&frt_min)*10,.01);
  if dqifscr&day&gt10 then dqifscr&day=10;

 *Sugar*;
  modspct&day=(asugar&day/&sug_max)*100;
  modsugs&day=(.<modspct&day<=100)*2.5
             +(100<modspct&day<=150)*1.5
             +(150<modspct&day<=200)*1.0
             +(200<modspct&day)*0;
 end;

%MEND;  /* end of dqi macro  */

*kcallo and kcalup are the lower and upper limits of kilocalories ;
*minimum servings of grains, veges, and fruits change depending on caloric intake;
***MACRO dqi(kcallo,kcalup,grn_min,frt_min,veg_min,sug_max);
         %dqi(0,1800,6,2,3,6)
         %dqi(1800,2600,9,3,4,12)
         %dqi(2600,99999,11,4,5,18)

**Create Moderation Scores;

**Alcohol;
if (.<alcnum&day) then do; 
 if gender=1 then 
   modapct&day=(alcnum&day/2)*100;
 else
  if gender=2 then 
   modapct&day=(alcnum&day/1)*100;
 modetos&day=(.<modapct&day<=100)*2.5
            +(100<modapct&day<=150)*1.5
            +(150<modapct&day<=200)*1.0
            +(200<modapct&day)*0;

** compute for alcohol drinkers only ***;
 if alcnum&day&gt0 then do;
   alcdrnk&day=1;  ** create if person drinks alcohol or not;
   adrink&day=alcnum&day; ** create # of alcohol drinks if person drinks; 
  end;
 else do;
   alcdrnk&day=0;
   adrink&day=.;
  end;

end;  *** end of (.<alcnum&day) do loop;

**Sodium;
if (.<sodium&day) then do;
  modnas&day=(   .<sodium&day<=2400)*2.5
            +(2400<sodium&day<=3400)*1.5
            +(3400<sodium&day)*0;
end;

** Check program;
  retain count 0;
  count=count+1;
  if count<10 then put hhid personid modsugs&day= '  ' modspct&day= '  ' asugar&day=; 
  if count<10 then put hhid personid modetos&day= '  ' modapct&day= '  ' alcnum&day= '  ' alcdrnk&day= '  ' adrink&day=;
  if count<10 then put hhid personid  modnas&day= '  '  sodium&day=;

* Create Moderation Score for Discretionary Fat;
 if dfat&day&gt. then do;
  moddfs&day=( .< dfat&day< 25)*2.5
             +(25<=dfat&day<=50)*1.5
             +(50< dfat&day< 75)*1.0
             +(75<=dfat&day)*0;
 end; ** end of dfat&day&gt. do loop;

* Create Moderation Score (a 10 point score) ;
  d&day.ms=modsugs&day
          +modetos&day
          +modnas&day
          +moddfs&day;

* Create Diet Quality Index Revised (100pt Score);
  d&day.dqi_r=efatscr&day
              +esftscr&day
              +cholscr&day
              +dqigscr&day
              +dqivscr&day
              +dqifscr&day
              +aicscr&day 
              +rdaiscr&day
              +d&day.dvswtd
              +d&day.ms;

**Check program;
if count<10 then put dfat&day=  moddfs&day= ;
if count<10 then put d&day.ms=   modsugs&day=   modetos&day=   modnas&day=   moddfs&day=;

%MEND;  /* end of dataday macro  */

%dataday(1)
%dataday(2)

label
 alcdrnk1 = "Day1 Tot: Alcohol Drinker" 
 alcdrnk2 = "2-Day Avg: Alcohol Drinker" 
 adrink1  = "Day1: Tot alc drinks of alcohol drinker"
 adrink2  = "2-Day: Avg alc drinks of alcohol drinker"
 
 modetos1 = "Day1: Moderation of Alcohol Score"
 modnas1  = "Day1: Moderation of Sodium Score"
 modsugs1 = "Day1: Moderation of Added Sugar Score"
 
 modetos2 = "2-Day Avg: Moderation of Alcohol Score"
 modnas2  = "2-Day Avg: Moderation of Sodium Score"
 modsugs2 = "2-Day Avg: Mod. of Added Sugar Score"
 
 dqigpct1 = "Day1 Total: DQI Tot Grains % of Min" 
 dqifpct1 = "Day1 Total: DQI Total Fruit % of Min"
 dqivpct1 = 'Day1 Total: DQI Total Veges&Soy % of Min'
 modapct1 = "Day1 Total: Mod of Alcohol % of Min"
 modspct1 = "Day1 Total: Mod of Added Sugar % of Min"
 dqigscr1 = "Day1 Total: DQI Total Grains 10pt score" 
 dqifscr1 = "Day1 Total: DQI Total Fruit 10pt score"
 dqivscr1 = 'Day1 Total: DQI Tot Veges&Soy 10pt scr'

 dqigpct2 = "2-Day Avg: DQI Tot Grains % of Min" 
 dqifpct2 = "2-Day Avg: DQI Total Fruit % of Min"
 dqivpct2 = '2-Day Avg: DQI Total Veges&Soy % of Min'
 modapct2 = "2-Day Avg: Mod of Alcohol % of Min"
 modspct2 = "2-Day Avg: Mod of Added Sugar % of Min"
 dqigscr2 = "2-Day Avg: DQI Total Grains 10pt score" 
 dqifscr2 = "2-Day Avg: DQI Total Fruit 10pt score"
 dqivscr2 = '2-Day Avg: DQI Tot Veges&Soy 10pt scr'

 moddfs1  = "Day1 Total: Moderation of Disc fat Score"
 moddfs2  = "2-Day Avg : Moderation of Disc fat Score"
 d1ms     = "Day1 Total: Moderation Score(10pt score)"
 d2ms     = "2-Day Avg : Moderation Score(10pt score)"

 d1dqi_r  = "Day1 Tot: DQI-Revised (100pt score)"
 d2dqi_r  = "2-Day Avg:DQI-Revised (100pt score)"
;;;

run;

proc freq data=csf9602;
tables graingrp;
title3 "Check that all food groups have been assigned.";
run;

options &land1;
proc print data=data.csf9634; 
where dayct=1 and (comp_d1=1 and comp_d2=1);
title3 "People who Fasted on either Day1 or Day2";
title4 "Day1 fasters should be only people with no day1 total";
run;

title3 " "; ** clears title3;

proc means data=data.csf9634;
run;
proc contents data=data.csf9634;
run;

endsas;

options &por;
proc print data=notfound noobs;
var foodcode fooddesc;
where graingrp=0 and (58000000<=foodcode<59000000);
title3 'Foodcode in the 58s that were not grouped by this program';
run;

proc sort data=csf9602 (keep=foodcode fooddesc graingrp) nodupkey; by foodcode;
run;

proc print data=csf9602 noobs;
 var foodcode graingrp fooddesc;
where graingrp&gt0;
title2 'Foodcodes in csf9602 where graingrp&gt0';
run;

proc print data=csf9634 (obs=50); var hhid personid age gender 
 fat1 dfat1 moddfs1 calc1 paicalc1 aicscr1 rdairon1 rdaiscr1
 fat2 dfat2 moddfs2 calc2 paicalc2 aicscr2 rdairon2 rdaiscr2;

proc print data=csf9634 (obs=50); var hhid personid age gender 
 dqigpct1 dqigscr1 dqifpct1 dqifscr1 dqivpct1 dqivscr1 modspct1 modapct1
 dqigpct2 dqigscr2 dqifpct2 dqifscr2 dqivpct2 dqivscr2 modspct2 modapct2;
run;