<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" >

<channel><title><![CDATA[BAILEY DEBARMORE - EPICODE]]></title><link><![CDATA[http://www.baileydebarmore.com/epicode]]></link><description><![CDATA[EPICODE]]></description><pubDate>Tue, 14 Jan 2025 22:43:04 -0500</pubDate><generator>Weebly</generator><item><title><![CDATA[Importing your Data into SAS, Stata, and R]]></title><link><![CDATA[http://www.baileydebarmore.com/epicode/importing-your-data-into-sas-stata-and-r]]></link><comments><![CDATA[http://www.baileydebarmore.com/epicode/importing-your-data-into-sas-stata-and-r#comments]]></comments><pubDate>Wed, 24 Mar 2021 18:01:51 GMT</pubDate><category><![CDATA[R]]></category><category><![CDATA[SAS]]></category><category><![CDATA[Stata]]></category><guid isPermaLink="false">http://www.baileydebarmore.com/epicode/importing-your-data-into-sas-stata-and-r</guid><description><![CDATA[Author: Bailey DeBarmoreIn a previous post, I talked you through how to get your data clean in Excel before importing to Stata, SAS, or R [read that post here].&nbsp;The next step is to import that data and start creating variables you need for analysis and running descriptives. I'll go through how to import your data in this post.Feel free to post questions in the comments!Jump to:StataSASR&nbsp;StataThe best way to import data into Stata is to use the menu and have Stata do it for you. Once yo [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><em><font size="1">Author: Bailey DeBarmore</font></em></div><div class="paragraph" style="text-align:left;"><span>In a previous post, I talked you through how to get your data clean in Excel before importing to Stata, SAS, or R [<strong><a href="http://www.baileydebarmore.com/epicode/cleaning-survey-data-for-analysis" target="_blank">read that post here</a></strong>].&nbsp;</span><span>The next step is to import that data and start creating variables you need for analysis and running descriptives. I'll go through how to import your data in this post.</span><br><br>Feel free to post questions in the comments!</div><div><!--BLOG_SUMMARY_END--></div><div class="paragraph">Jump to:<br><strong><a href="http://www.baileydebarmore.com/epicode/importing-your-data-into-sas-stata-and-r#Stata">Stata</a><br><a href="http://www.baileydebarmore.com/epicode/importing-your-data-into-sas-stata-and-r#SAS">SAS</a><br><a href="http://www.baileydebarmore.com/epicode/importing-your-data-into-sas-stata-and-r#R">R</a></strong></div><div><div id="698295544886948730" align="left" style="width: 100%; overflow-y: hidden;" class="wcustomhtml"><a name="Stata" id="Stata">&nbsp;</a></div></div><h2 class="wsite-content-title">Stata</h2><div class="paragraph" style="text-align:left;">The best way to import data into Stata is to use the menu and have Stata do it for you. Once you import the data, you'll be able to copy the commands you need and save to your do file for the future. So I'm going to walk you through how to use the click menu rather than sharing syntax that changes from version to version in Stata.<br><br>Before we do that, let's talk about setting the working directory. If you are pulling files from multiple locations on your computer, you'll want to save the code (cd) to your do file so you can move around. We'll first use the click menu to produce the code.</div><div><div class="wsite-image wsite-image-border-none" style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"><a><img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/stata-wd1_orig.png" alt="Picture" style="width:auto;max-width:100%"></a><div style="display:block;font-size:90%"></div></div></div><div class="paragraph">Type cd followed by the path name in double quotes.&nbsp;</div><blockquote>&#8203;cd "C:\Users\bailey\EPICODE"</blockquote><div><div class="wsite-image wsite-image-border-none" style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"><a><img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/stata-file-import_orig.png" alt="Picture" style="width:auto;max-width:100%"></a><div style="display:block;font-size:90%"></div></div></div><div class="paragraph" style="text-align:left;"><strong>Excel file (.xls, xlsx)</strong><br><br>If your data is in an Excel file, you can import a specific worksheet using&nbsp; File &gt; Import &gt; Excel spreadsheet. When the new window opens, click BROWSE to find your Excel file. Then, fill out the correct options. You'll see a preview of your data. You want to make sure you select 'first row as variable names' if that applies, and decide whether you want to preserve case or not. Since Stata is case-sensitive, if you named your variables like Gender, SchoolID, etc. you will need to always refer to them that way (not gender, schoolid). If you decide you want to do all lowercase or all uppercase, you can select those options in the dropdown.&nbsp;<br><br>When you're ready, hit OK and you should see the variable window populate. Final step is to go to File &gt; Save as and save this data set as a Stata dataset (.dta) - you don't want to import it every time you need to work on it.<br></div><div><div class="wsite-image wsite-image-border-none" style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"><a><img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/stata-file-import-excel_orig.png" alt="Picture" style="width:auto;max-width:100%"></a><div style="display:block;font-size:90%"></div></div></div><div class="paragraph"><span>&#8203;<br>&#8203;Link to&nbsp;</span><a href="https://www.stata.com/manuals14/dimportexcel.pdf#dimportexcel" target="_blank">Stata Manual for import excel</a><br><br><span>I'm using Stata14 and when I did the click menu steps above to import my data, the resulting syntax was:</span></div><blockquote><span style="color:rgb(42, 42, 42)">&#8203;import excel "C:\Users\bailey\EPICODE\example-survey.xlsx", sheet("&lt;sheetname&gt;") firstrow<br>&#8203;import excel "&lt;location\dataset.xlsx&gt;", sheet("&lt;sheetname&gt;") firstrow</span><br></blockquote><div class="paragraph" style="text-align:left;"><span>&lt;Location&gt; is the C:\User path where the xlsx file can be found, and dataset.xlsx is the Excel file name.</span><br>&lt;Sheetname&gt; is the name of the specific worksheet in my Excel document<br>The option firstrow told Stata to import the first row as variable names<br><br>If you're importing multiple files, you can copy this syntax into your do file and change the path name/document name, and then save to easily run these commands over and over again. This is useful if you are appending or merging multiple files.</div><blockquote><span style="color:rgb(42, 42, 42)">&#8203;import excel "&lt;location\dataset1.xlsx&gt;", sheet("&lt;sheetname&gt;") firstrow</span><br>save "&lt;location\dataset1.dta&gt;", replace<br><br><span style="color:rgb(42, 42, 42)">&#8203;import excel "&lt;location\dataset2.xlsx&gt;", sheet("&lt;sheetname&gt;") firstrow</span><br><span style="color:rgb(42, 42, 42)">save "&lt;location\dataset2.dta&gt;", replace</span></blockquote><div class="paragraph" style="text-align:left;"><strong>Delimited file (.csv, .tsv, .txt)</strong><br><br>Delimited files have information in columns and rows seaparate by 'delimieters' which are often a comma (csv), tab (tsv), or comma, tab, space, linebreaks, and others (txt). Often you may have a dataset that is a csv but opened in Excel. Or you may have one that opens in a text file. Either way, when you choose File &gt; Import &gt; Delimited, Stata will automatically identify the delimiter for you. It will also detect if you have variables in the first row or not. Similar to the Excel import, you can choose to preserve SnakeCase variable names or not.<br><br></div><div><div class="wsite-image wsite-image-border-none" style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"><a><img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/stata-file-import-delimited_orig.png" alt="Picture" style="width:auto;max-width:100%"></a><div style="display:block;font-size:90%"></div></div></div><div class="paragraph" style="text-align:left;"><br><span>Link to&nbsp;</span><a href="https://www.stata.com/manuals14/dimportdelimited.pdf#dimportdelimited" target="_blank">Stata Manual for import delimited</a><br><br>When I import a csv to Stata14, I get the following syntax that I can save in my do file for later. There are no quotation marks and you don't include the &lt;&gt;, those are just here as an example.</div><blockquote>&#8203;import delimited <span style="color:rgb(42, 42, 42)">C:\Users\bailey\EPICODE\example-survey.csv<br></span></blockquote><div class="paragraph" style="text-align:left;"><span>&lt;Location&gt; is the C:\User path where the csv file can be found, and dataset.csv is the file name.</span><br><br><span>If you're importing multiple files, you can copy this syntax into your do file and change the path name/document name, and then save to easily run these commands over and over again. This is useful if you are appending or merging multiple files. See below how I change the working directory with a cd command without ever leaving my do file.</span></div><blockquote><span style="color:rgb(42, 42, 42)">&#8203;cd "C:\Users\bailey\EPICODE"&#8203;<br>import delimited dataset1.csv<br>save "dataset1.dta", replace<br><br>&#8203;cd "C:\Users\bailey\EPICODE\data"<br>&#8203;import delimited dataset2.csv</span><br><span style="color:rgb(42, 42, 42)">&#8203;</span><span style="color:rgb(42, 42, 42)">save "dataset2.dta", replace</span></blockquote><div class="paragraph" style="text-align:left;"><strong>&#8203;SAS XPORT (.xport)</strong><br>I don't have a screenshot for importing a SAS XPORT file but it follows the same logic as the Excel and delimited files. Go to File &gt; Import &gt; SAS XPORT, browse for your file, select any options, and press OK. Then File &gt; Save As to save it as a Stata dataset (.dta)<br><br>Link to <a href="https://www.stata.com/manuals14/dimportsasxport.pdf#dimportsasxport" target="_blank">Stata Manual for import sasxport</a><br><br><strong>SAS (.sas)</strong><br>If you need to import a SAS data file into Stata and it is .sas (not XPORT) then the best way is to export it from SAS as a .dta file (which is the Stata dataset file type). Just as SAS has a click menu option for import, you can also use it for export (see images and code below).<br><br>&#8203;Then you can easily open it in Stata by double-clicking the file in your folder or going to File &gt; Open and browsing for it.</div><div><div class="wsite-image wsite-image-border-none" style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"><a><img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/sas-file-export-stata_orig.png" alt="Picture" style="width:auto;max-width:100%"></a><div style="display:block;font-size:90%"></div></div></div><blockquote>PROC EXPORT DATA= WORK.EXAMPLESURVEY&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OUTFILE= "C:\Users\bailey\EPICODE\examplesurvey2.dta"&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DBMS=STATA REPLACE;<br>RUN;</blockquote><div class="paragraph">&#8203;If you choose to have SAS save the export code, you'll get code like the one above.<br><br><span>The key elements are</span><ul><li>PROC EXPORT statement: what is the name of the SAS dataset you want to export? Where is it located?<ul><li>OUTFILE: where should SAS save&nbsp;your exported dataset and what should it call it? Put the path and dataset in double quotes.</li><li>DBMS: Specify the type of file it should export to - here it is Stata (note that in the OUTFILE portion I also did .dta after the new dataset name)</li></ul></li></ul></div><div><div id="542223838664326579" align="left" style="width: 100%; overflow-y: hidden;" class="wcustomhtml"><a name="SAS" id="SAS">&nbsp;</a></div></div><h2 class="wsite-content-title">SAS</h2><div class="paragraph" style="text-align:left;"><span>Usually, the best way to import data into SAS is to use the Import Wizard and have SAS do it for you. During the import process, you can choose to have SAS save the commands in an Editor that you can access and save the code for later. I provide screenshots below on how to use the&nbsp;Import Wizard and the resulting code for you.<br><br>Before we get into that, be sure you've run your libname statement which tells SAS where to go look for data. I typically like to have a lib for where it will pull data from, where it will put data, and where it will save files. Type 'libname', then name the lib, and then encase the path in double quotes.</span></div><blockquote>libname data <span style="color:rgb(42, 42, 42)">"C:\Users\bailey\EPICODE\data"<br>&#8203;libname files&nbsp;&#8203;"C:\Users\bailey\EPICODE\output"</span></blockquote><div><div class="wsite-image wsite-image-border-none" style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"><a><img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/sas-file-import_orig.png" alt="Picture" style="width:auto;max-width:100%"></a><div style="display:block;font-size:90%"></div></div></div><div class="paragraph" style="text-align:left;"><strong>Excel files (.xls, .xlsx)</strong><br><span>Using File &gt; Import and then selecting Excel in the dropdown, you can import an Excel file into SAS. When you go to browse, make sure that in file type you have "All Files" or specifically "xls" or "xlsx" selected so that your file of choice shows up.</span><br><br><span>&#8203;In the final screen, if you select a location for SAS to save an editor file, you will get code like the code below that you can reuse later.&nbsp; If you're having trouble with the import wizard (like you're getting an error that says it cannot connect to MS Excel) try running the code provided below.</span></div><div><div class="wsite-image wsite-image-border-none" style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"><a><img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/sas-file-import-excel_orig.png" alt="Picture" style="width:auto;max-width:100%"></a><div style="display:block;font-size:90%"></div></div></div><blockquote><span style="color:rgb(42, 42, 42)">PROC IMPORT OUT= WORK.examplesurvey&nbsp;</span><br><span style="color:rgb(42, 42, 42)">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DATAFILE= "C:\Users\bailey\EPICODE\example-survey.xlsx"&nbsp;</span><br><span style="color:rgb(42, 42, 42)">&#8203;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;DBMS=XLSX REPLACE;</span><br><span style="color:rgb(42, 42, 42)">&nbsp; &nbsp; &nbsp;SHEET="auto";<br>&nbsp; &nbsp; &nbsp;GETNAME=YES;</span><br><span style="color:rgb(42, 42, 42)">RUN;<br><br>DATA LIB.examplesurvey;</span><br>&nbsp; &nbsp; &nbsp;SET WORK.examplesurvey;<br>&#8203;RUN;</blockquote><div class="paragraph" style="text-align:left;"><br><span>The key elements are</span><ul><li>PROC IMPORT statement: what will you name your new SAS data set? Do you want it to be in the work library or another lib? Make sure you have libname statement previously to establish that library in that SAS working session.<ul><li>DATAFILE: where should SAS look for your file? Put the path and dataset in double quotes.</li><li>DBMS: Then you specify the file type (CSV here) after DBMS=. In the example below when we import a Stata file, intsead of CSV we write STATA. Replace tells SAS to replace any dataset already named examplesurvey in the WORK lib.</li></ul></li><li>SHEET statement: The 'auto' option is the default and SAS will import the first sheet in the workbook. You can instead specify a sheet name with quotes.</li><li>GETNAME: If variable names are in the first row, then use YES and SAS will pull those in.</li></ul><br><span>When you're done importing, run a data step to save the data in your lib of choice.</span></div><div class="paragraph" style="text-align:left;"><strong>Delimited files</strong><br><br>Using File &gt; Import and then selecting CSV in the dropdown, you can import a csv file into SAS. In the final screen, if you select a location for SAS to save an editor file, you will get code like the code below that you can reuse later.&nbsp;<br></div><div><div class="wsite-image wsite-image-border-none" style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"><a><img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/sas-import-csv-1_orig.png" alt="Picture" style="width:auto;max-width:100%"></a><div style="display:block;font-size:90%"></div></div></div><blockquote>PROC IMPORT OUT= WORK.examplesurvey&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DATAFILE= "C:\Users\bailey\EPICODE\example-survey.csv"&nbsp;<br>&#8203;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;DBMS=CSV REPLACE;<br>&nbsp; &nbsp; &nbsp;GETNAMES=YES;<br>&nbsp; &nbsp; &nbsp;DATAROW=2;&nbsp;<br>RUN;<br><br>&#8203;<span style="color:rgb(42, 42, 42)">DATA LIB.examplesurvey;</span><br><span style="color:rgb(42, 42, 42)">&nbsp; &nbsp; SET WORK.examplesurvey;</span><br><span style="color:rgb(42, 42, 42)">&#8203;RUN;</span></blockquote><div class="paragraph" style="text-align:left;"><span>The key elements are</span><ul><li>PROC IMPORT statement: what will you name your new SAS data set? Do you want it to be in the work library or another lib? Make sure you have libname statement previously to establish that library in that SAS working session.<ul><li>DATAFILE: where should SAS look for your file? Put the path and dataset in double quotes.</li><li>DBMS: Then you specify the file type (CSV here) after DBMS=. In the example below when we import a Stata file, intsead of CSV we write STATA. Replace tells SAS to replace any dataset already named examplesurvey in the WORK lib.</li></ul></li><li>GETNAMES statement: Get variable names from the first row</li><li>DATAROW: Data starts in row 2</li></ul><br><span>If you're importing a Delimited (.) or Text (.txt) file then instead of choosing CSV in the drop-down, select those options. They will replace the CSV in the DBMS part of the PROC IMPORT statement.</span><br><br><span>&#8203;</span><span>When you're done importing, run a data step to save the data in your lib of choice. In the example above I have LIB.examplesurvey where LIB is just a placeholder for whatever you named your lib. If we're following my libname statements from the beginning of this section, it would be data.examplesurvey.</span></div><div class="paragraph" style="text-align:left;"><strong>Stata file (.dta)</strong><br><span>Using File &gt; Import and then selecting Stata in the dropdown, you can import a Stata data file into SAS. In the final screen, if you select a location for SAS to save an editor file, you will get code like the code below that you can reuse later.&nbsp;</span></div><div><div class="wsite-image wsite-image-border-none" style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"><a><img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/sas-file-import-stata_orig.png" alt="Picture" style="width:auto;max-width:100%"></a><div style="display:block;font-size:90%"></div></div></div><blockquote>PROC IMPORT OUT= WORK.EXAMPLESURVEY2&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DATAFILE= "C:\Users\baile\Dropbox\EPICODE\survey\example-survey.dta"&nbsp;<br>&#8203;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DBMS=STATA REPLACE;<br>RUN;<br><br>&#8203;<span style="color:rgb(42, 42, 42)">DATA LIB.examplesurvey;</span><br><span style="color:rgb(42, 42, 42)">&nbsp; &nbsp; SET WORK.examplesurvey;</span><br><span style="color:rgb(42, 42, 42)">&#8203;RUN;</span></blockquote><div class="paragraph" style="text-align:left;"><span>The key elements are</span><br><span>PROC IMPORT statement: what will you name your new SAS data set? Do you want it to be in the work library or another lib? Make sure you have libname statement previously to establish that library in that SAS working session.</span><ul><li>DATAFILE: where should SAS look for your file? Put the path and dataset in double quotes.</li><li>DBMS: Then you specify the file type (Stata here) after DBMS=. In the example above when we import a csv file, instead of STATA we write CSV. Replace tells SAS to replace any dataset already named examplesurvey in the WORK lib.&#8203;&#8203;<br>&#8203;</li></ul><span>When you're done importing, run a data step to save the data in your lib of choice.</span></div><div><div id="955773965690812406" align="left" style="width: 100%; overflow-y: hidden;" class="wcustomhtml"><a name="R" id="R">&nbsp;</a></div></div><h2 class="wsite-content-title">R</h2><div class="paragraph" style="text-align:left;">Just like with SAS and Stata, you can use the click menu to import data. Go to File &gt; Import Dataset and select From Text (base), From Excel, From SPSS, From SAS, From Stata. The code will appear in your console and you can save it in your script.<br></div><div><div class="wsite-image wsite-image-border-none" style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"><a><img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/r-import_orig.png" alt="Picture" style="width:auto;max-width:100%"></a><div style="display:block;font-size:90%"></div></div></div><div class="paragraph" style="text-align:left;"><span>To set your working directory in R, use 'setwd' and enclose the path in quotes and parentheses. If you have data in R format already (.rds) you can read in using readRDS and save out using saveRDS. Filenames also need to be in quotes.<br><br>If you set your working directory (wd) then in the following examples, you would be able to simply refer to the file name rather than the full file path if you are typing out your code. Otherwise you can always specify the full path, especially if you're pulling in data form multiple locations. In addition&nbsp;to the code below, you can use the click menu to set your working&nbsp;directory. Go to Session &gt; Set Working Directory &gt; Choose Directory.</span></div><blockquote>setwd("<span style="color:rgb(42, 42, 42)">C:/Users/bailey/EPICODE</span>")<br>examplesurvey &lt;- readRDS("example-survey.rds")<br>saveRDS(examplesurvey, file="examplesurvey_final.rds")</blockquote><div><div class="wsite-image wsite-image-border-none" style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"><a><img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/r-wd_orig.png" alt="Picture" style="width:auto;max-width:100%"></a><div style="display:block;font-size:90%"></div></div></div><div class="paragraph" style="text-align:left;">To read in data in other formats, you can use read.csv(), read.xls(), read.spss(), read.dta(), read.delim(), read.table(). There are also packages like haven that you can use to read SAS files (read_sas()). Haven will also read Stata files (.dta) and other file types.<br></div><div class="paragraph" style="text-align:left;"><strong>Excel (.xls, .xlsx)</strong><br>To import my xlsx file, I used File &gt; Import Dataset &gt; From Excel. Then I browsed for my file, and checked the options in the bottom right - first name as variables, correct sheet, etc.<br><br>The code R used was from the readxl package, using read_excel, because base R only has a function for xls files, not xlsx. In the code below, I've read in my file example-survey-1.xslx to R as the object example_survey_1.&nbsp;</div><blockquote>library(readxl)<br>example_survey_1 &lt;- read_excel("C:/Users/bailey/EPICODE/example-survey-1.xlsx")<br></blockquote><div><div class="wsite-image wsite-image-border-none" style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"><a><img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/r-import-excel_orig.png" alt="Picture" style="width:auto;max-width:100%"></a><div style="display:block;font-size:90%"></div></div></div><div class="paragraph"><strong>Delimited files (csv)</strong></div><div class="paragraph" style="text-align:left;">To import my csv file, I go to File &gt; Import Dataset &gt; From Text (base). Immediately, the file browser comes up. When I select my file, I can check the options - such as first row as variable names, and look at the preview. The resulting code in my console is:</div><blockquote>example.survey &lt;- read.csv("C:/Users/bailey/EPICODE/example-survey.csv")</blockquote><div class="paragraph" style="text-align:left;">R simply used the base R function read.csv to read in the file and named it with the same name.</div><div><div class="wsite-image wsite-image-border-none" style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"><a><img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/r-import-csv_orig.png" alt="Picture" style="width:auto;max-width:100%"></a><div style="display:block;font-size:90%"></div></div></div><div class="paragraph"><strong>&#8203;SAS (.sas, .sas7bdat)<br>&#8203;</strong><span>To use the haven package, install it, load it with the library function, and then use read_sas() and the file extension .sas7bdat to read it into R.<br><br>You can also use File &gt; Import Dataset &gt; From SAS and R will produce the code for you.</span></div><blockquote>install.packages('haven')<br>library(haven)<br>examplesurvey &lt;- read_sas("examplesurvey.sas7bdat")</blockquote><div class="paragraph"><strong>Stata (.dta)<br>&#8203;</strong><span>To use the haven package, install it, load it with the library function, and then use read_dta() and the file extension .dta to read it into R.<br><br>You can also use File &gt; Import Dataset &gt; From Stata and R will produce the code for you.</span></div><blockquote><span style="color:rgb(42, 42, 42)">install.packages('haven')</span><br><span style="color:rgb(42, 42, 42)">library(haven)</span><br>&#8203;&#8203;examplesurvey &lt;- read_dta(<span style="color:rgb(42, 42, 42)">"C:/Users/bailey/EPICODE/examplesurvey.dta")</span></blockquote><div><div class="wsite-image wsite-image-border-none" style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"><a><img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/r-import-stata_orig.png" alt="Picture" style="width:auto;max-width:100%"></a><div style="display:block;font-size:90%"></div></div></div>]]></content:encoded></item><item><title><![CDATA[Cleaning Survey Data for Analysis]]></title><link><![CDATA[http://www.baileydebarmore.com/epicode/cleaning-survey-data-for-analysis]]></link><comments><![CDATA[http://www.baileydebarmore.com/epicode/cleaning-survey-data-for-analysis#comments]]></comments><pubDate>Tue, 09 Mar 2021 16:05:50 GMT</pubDate><category><![CDATA[Bailey DeBarmore]]></category><category><![CDATA[Excel]]></category><category><![CDATA[R]]></category><category><![CDATA[SAS]]></category><category><![CDATA[Stata]]></category><guid isPermaLink="false">http://www.baileydebarmore.com/epicode/cleaning-survey-data-for-analysis</guid><description><![CDATA[Author: Bailey DeBarmore  A task I often help with is getting survey data prepped for data analysis. Typically a client has distributed a written survey via Qualtrics or SurveyMonkey, and has downloaded the survey results to Excel as an xls, xlsx, or csv.Before importing that data into Stata, SAS, or R, [read that post here] there are a few steps you should do first. In this short tutorial post, I'll walk you through those steps. I highly recommend reading through this post in full before touchi [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><em><font size="1">Author: Bailey DeBarmore</font></em></div>  <div class="paragraph" style="text-align:left;">A task I often help with is getting survey data prepped for data analysis. Typically a client has distributed a written survey via Qualtrics or SurveyMonkey, and has downloaded the survey results to Excel as an xls, xlsx, or csv.<br /><br />Before importing that data into Stata, SAS, or R, [<strong><a href="http://www.baileydebarmore.com/epicode/importing-your-data-into-sas-stata-and-r" target="_blank">read that post here</a></strong>] there are a few steps you should do first. In this short tutorial post, I'll walk you through those steps. I highly recommend reading through this post in full before touching your data. Get an overview of what you'll need to do and then read through again to let the gears turn on how you'll need to clean your own data.<br /><br />Feel free to post any questions in the comments!&nbsp;<br /><br />&#8203;Let's get started.</div>  <div>  <!--BLOG_SUMMARY_END--></div>  <div class="paragraph" style="text-align:left;">The screenshots used in this short tutorial are provided in slideshow form below as well as with associated text in the post.</div>  <div><div style="height:20px;overflow:hidden"></div> <div id='833370010761356052-slideshow'></div> <div style="height:20px;overflow:hidden"></div></div>  <h2 class="wsite-content-title" style="text-align:left;">download your data from the survey platform</h2>  <div class="paragraph" style="text-align:left;">If you haven't already, download your data from the survey platform that you used (e.g., Qualtrics, SurveyMonkey). You may have the option to download it WITH LABELS or AS NUMBERS. The photos below show you what that means. Basically, with labels, means that if you asked respondents "How much do you agree with this statement?" and the options were Strongly Agree, Agree, Neutral, Disagree, Strongly Disagree, downloading the data with labels would export those terms while downloading the data with numbers would turn that into 1, 2, 3, 4, 5, or 5, 4, 3, 2, 1.&nbsp;<br /><br />&#8203;I recommend downloading WITH LABELS and then recoding yourself.<br /></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/1-survey-withlabels-epicode_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/2-survey-withnumbers-epicode_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;">You may have columns for timestamp (like I've simulated here), duration, IP address, etc. etc. etc. You can go ahead and get rid of those columns if you don't need it.&nbsp;<br /><br />You'll see that your question number is in the top row (which we reserve for variable names) with extra information, such as the question text, in row 2. What we'll do next is create a codebook where we can save information like that question text for easy reference as we clean the data.<br /><br />You'll notice that longer text, like your question text, is cut-off. Don't bother using 'wrap text'. Instead, select the sell and view the text in the top box like I've indicated in the image below. We'll be getting rid of that second row anyways, and as you re-code things like perhaps topic coding of qualitative responses, you can easily see the text in the top box.<br /></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/4-survey-wraptext-epicode_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <h2 class="wsite-content-title">create a codebook</h2>  <div class="paragraph" style="text-align:left;">If you haven't done this already, you'll want to make a codebook. You can do this in Excel or a word processor, whichever you prefer. You'll want to include the new variable name, the values, the labels for those values, and the name of the old variable or variables it was created for. In this simple example, you can see that I have the possible values from my survey under "values" and have assigned them a numeric label in column C. I've also copied over the question text so that I can delete it from my data sheet. You will likely want to reference this document while you clean your data, so I suggest making it in a new worksheet or in Word so you can have it side-by-side to your data. You can also screenshot it and paste into your data sheet or print it out. Whatever works for you!</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/3-survey-codebook-epicode_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <h2 class="wsite-content-title">recode with new variables</h2>  <div class="paragraph" style="text-align:left;">For each new variable, you're going to insert a new column. You can see that Q1 asked about gender and exported to column C, and I made a new column (column D below), and named that variable (column), gender. Per my codebook (above), cis-male is coded as 0, cis-female as 1, nonbinary as 2, and in this simulated data there were no responses for trans-male or trans-female, but if there were, they would be 3 and 4.&nbsp;<br /><br />I'll talk about filtering and sorting in the next step, so just keep reading before you start changing your data.<br /><br />I made a new variable for Q2, called age, and copied the numbers over. If you were going to create age categories from the age variable, you could do that, too.&nbsp;<br /><br />For race (Q3), respondents could "select all that apply" which is shown in rows 7 and 8. To recode this variable into "race" (column H) I followed the coding in my codebook, where someone that indicated more than one race has a separate category. How you choose to code race and "select all that apply" variables, is up to you and your research question.&nbsp;<br /><br />For binary variables (variables with yes/no options), you want to name the variable so that you inherently know which value is coded as 1. For example, instead of making a variable for Q4 called "ethnicity", I named it "hispanic" so that it's easy for me (and anyone else using my data) to know that data for that variable is coded as 1 = Hispanic/Latinx and 0 = Not Hispanic/Latinx. If you want to make a combined race/ethnicity variable, you could do that here in Excel, or if you're comfortable in SAS, Stata, or R, you can make it later (which is what I would do).<br /><br />Note - I made the new variable names bold just so it was easier for you to see.<br /></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/5-survey-recode-epicode_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;">As we move through the variables, when we have more than 2 or 3 categories it is easier to filter or sort the data rows rather than going row by row assigning different values. If you haven't already, you'll want to get rid of the question text in row 2 because when you go to filter (up at the top - Sort &amp; Filter - Filter), that row will get sorted as well (see second image below).<br /><br />In the image below you can see I went ahead and made new variables for Q5 (year) and Q6 (phd). For year, which was reported as 1st, 2nd, 3rd, 4th, 5th, etc. I coded it as 1, 2, 3, 4 or 5. You may choose to code it has 1st year or older, in which case you would make a variable called "firstyear" with 1 = 1st year, 0 = 2nd year and above. You could make a cut-off at any value, or a categorical variable such as 0 = 1st and 2nd years, 1 = 3rd and 4th years, 2 =- 5th years and above. How you code your variables depends on your research question!<br /><br />The only program options in this example were MSPH (Masters of Science in Public Health) and PhD (Doctorate of philosophy). I chose to make a variable called phd from Q6, but I easily could've made a variable called msph. If I named the variable msph, which value would be coded as 1? 0?<br /></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/6-survye-filter-epicode_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;">I prefer to select the FILTER option, rather than Sort A to Z from the menu, because it adds these little arrows to my first row (header, variables) and I can sort or select from there. Simply click the down arrow next to the variable name (Q3 below) and you'll have options to either Sort, or Select. You can do either. If you Select, for example if I only select PhD for Q6, it will hide rows where Q6 = MSPH. I can then fill in 1 for the rows under column N (phd), and then deselect PhD in column M, select MSPH, and fill in 0 for the rows that show in column N (phd). It's up to you which option you use and you don't always have to use the same one.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/7-survey-recode-epicode_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">Because this simulated data set is so small, and the codebook is easy to see on one screen, I used a screenshot to paste it onto my data sheet so it was easy to see what values correspond with what labels. In the image below, I clicked the arrow for Q7, sort A to Z, and filled in the 1 through 5 values in the column next to it (the new variable). Then I repeated that for the remaining questions.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/8-survey-recode-epicode_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <h2 class="wsite-content-title">ready to analyze the data</h2>  <div class="paragraph" style="text-align:left;">Here is my cleaned dataset, ready to import into Stata, SAS, or Excel. You'll want to select options that import your first row as variable names, and it's up to you if you want to keep the original variables (Q1, Q3, etc) or not. If you don't have many variables, you may opt to keep them so that when you browse your data it's easy to see the labels.&nbsp; If you do have a lot of variables, it would be better to make a copy of this sheet, save as, delete those columns, and then import that smaller dataset. Once you're in your software of choice, put your codebook side-by-side and apply labels to the values so it's easy for you to remember and for someone else to understand your data.<br /><br />SAS and Stata have a File &gt; Import function or an Import Wizard that makes importing an xls, xlsx, or csv file easy. They'll produce code in the command window that you can save later to reference. I've included some helpful links below to get you onto this next step.<br /></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/9-survey-ready-epicode_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div id="862767116927642463"><div><style type="text/css">	#element-7a8615d4-7a54-4dee-babe-2c8445f63f82 .colored-box-content {  clear: both;  float: left;  width: 100%;  -moz-box-sizing: border-box;  -webkit-box-sizing: border-box;  -ms-box-sizing: border-box;  box-sizing: border-box;  background-color: #f4f7f8;  padding-top: 20px;  padding-bottom: 20px;  padding-left: 20px;  padding-right: 20px;  -webkit-border-top-left-radius: 0px;  -moz-border-top-left-radius: 0px;  border-top-left-radius: 0px;  -webkit-border-top-right-radius: 0px;  -moz-border-top-right-radius: 0px;  border-top-right-radius: 0px;  -webkit-border-bottom-left-radius: 0px;  -moz-border-bottom-left-radius: 0px;  border-bottom-left-radius: 0px;  -webkit-border-bottom-right-radius: 0px;  -moz-border-bottom-right-radius: 0px;  border-bottom-right-radius: 0px;}</style><div id="element-7a8615d4-7a54-4dee-babe-2c8445f63f82" data-platform-element-id="848857247979793891-1.0.1" class="platform-element-contents">	<div class="colored-box">    <div class="colored-box-content">        <div style="width: auto"><div></div><div class="paragraph" style="text-align:left;">Ready to import your data? Head over to my blog post on <strong><a href="http://www.baileydebarmore.com/epicode/importing-your-data-into-sas-stata-and-r" target="_blank">Importing your data into SAS, Stata and R</a></strong>.</div></div>    </div></div></div><div style="clear:both;"></div></div></div>]]></content:encoded></item><item><title><![CDATA[Creating a Transition Matrix in Stata]]></title><link><![CDATA[http://www.baileydebarmore.com/epicode/creating-a-transition-matrix-in-stata]]></link><comments><![CDATA[http://www.baileydebarmore.com/epicode/creating-a-transition-matrix-in-stata#comments]]></comments><pubDate>Fri, 11 Sep 2020 16:57:59 GMT</pubDate><category><![CDATA[Bailey DeBarmore]]></category><category><![CDATA[Stata]]></category><guid isPermaLink="false">http://www.baileydebarmore.com/epicode/creating-a-transition-matrix-in-stata</guid><description><![CDATA[Author: Bailey DeBarmore  Do you want to model trajectories by calculating transition probabilities? You can do this in Stata with just a little extension of your longitudinal data analysis skills.We'll be using&nbsp;xttrans&nbsp;(built in to Stata) or&nbsp;xttrans2&nbsp;(a module you can download).&nbsp;Your data will need to be in LONG format. To reshape from wide to long, use:&nbsp;  reshape long&nbsp;stub,&nbsp;&#8203;i(id) j(time)  Where stub is the stubname of your variable, i is the varia [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><em><font size="1">Author: Bailey DeBarmore</font></em></div>  <div class="paragraph">Do you want to model trajectories by calculating transition probabilities? You can do this in Stata with just a little extension of your longitudinal data analysis skills.<br /><br />We'll be using&nbsp;<em>xttrans</em>&nbsp;(built in to Stata) or&nbsp;<em>xttrans2&nbsp;</em>(a module you can download).&nbsp;<br /><br />Your data will need to be in LONG format. To reshape from wide to long, use:&nbsp;</div>  <blockquote>reshape long&nbsp;<em>stub,&nbsp;</em>&#8203;i(id) j(time)</blockquote>  <div class="paragraph">Where stub is the stubname of your variable, i is the variable that uniquely identifies observations in your data set, and j is the time variable.&nbsp;<br /></div>  <div>  <!--BLOG_SUMMARY_END--></div>  <div class="paragraph"><span>What's a stubname? If you currently have variables status1, status2, status3 with participant status (dead/alive) at years 1, 2, and 3, your stubname would be&nbsp;</span><em>status&nbsp;</em><span>&nbsp;and your time variable (j) that we are creating would be year.&nbsp;</span>&#8203;</div>  <blockquote>reshape long status, i(id) j(year)</blockquote>  <div class="paragraph">The code above will create a new variable (column) called "year", and our long dataset will have 3 rows for each id (observation) and only one variable for status.&nbsp;<br /><br />It's normal to have your dataset saved in a wide and long format. You can also go back to wide by typing "reshape wide".&nbsp;</div>  <div id="195587489607682678"><div><style type="text/css">	#element-5b751991-49a1-4d1e-827a-820e784d35a6 .colored-box-content {  clear: both;  float: left;  width: 100%;  -moz-box-sizing: border-box;  -webkit-box-sizing: border-box;  -ms-box-sizing: border-box;  box-sizing: border-box;  background-color: #f4f7f8;  padding-top: 20px;  padding-bottom: 20px;  padding-left: 20px;  padding-right: 20px;  -webkit-border-top-left-radius: 0px;  -moz-border-top-left-radius: 0px;  border-top-left-radius: 0px;  -webkit-border-top-right-radius: 0px;  -moz-border-top-right-radius: 0px;  border-top-right-radius: 0px;  -webkit-border-bottom-left-radius: 0px;  -moz-border-bottom-left-radius: 0px;  border-bottom-left-radius: 0px;  -webkit-border-bottom-right-radius: 0px;  -moz-border-bottom-right-radius: 0px;  border-bottom-right-radius: 0px;}</style><div id="element-5b751991-49a1-4d1e-827a-820e784d35a6" data-platform-element-id="848857247979793891-1.0.1" class="platform-element-contents">	<div class="colored-box">    <div class="colored-box-content">        <div style="width: auto"><div></div><div class="paragraph"><strong>Helpful Links</strong><br />Reshape (Stata):&nbsp;<a href="https://www.stata.com/manuals13/dreshape.pdf">https://www.stata.com/manuals13/dreshape.pdf</a><br />xt (Stata):&nbsp;<a href="https://www.stata.com/manuals13/xt.pdf">https://www.stata.com/manuals13/xt.pdf</a><br />xttrans2 (Nicholas Cox):&nbsp;<a href="https://ideas.repec.org/c/boc/bocode/s416301.html">https://ideas.repec.org/c/boc/bocode/s416301.html</a>&nbsp;(<a href="https://fmwww.bc.edu/repec/bocode/x/xttrans2.html" target="_blank">help file here</a>)</div></div>    </div></div></div><div style="clear:both;"></div></div></div>  <div class="paragraph">First, xtset your data - you're telling Stata what variable uniquely identifies the "panels" since your long data form has repeated rows. For this example, it would be "xtset id".&nbsp;<br /><br />Then we can use xttrans &lt;var&gt; for our transition probabilities. Default is to just display probabilities. If you also want the frequency counts, you can use the option "freq". <br /><br />&#8203;We can also use "by" with xttrans.</div>  <blockquote>xtset id<br />xttrans status<br />&#8203;xttrans status, freq<br />xttrans status, by(sex)<br /></blockquote>  <div class="paragraph">xttrans2, a module written by Nicholas Cox, expands on xttab and xttrans. You can specify additional options (<a href="https://www.stata.com/manuals13/rtabulateoneway.pdf" target="_blank">the same options as tabulate</a>, except for row and freq) but you can't use "by".<br /><br />A big advantage of xttrans2 is that you can save the resulting probability matrix using the option <em>matcell</em>.</div>]]></content:encoded></item><item><title><![CDATA[Interpreting Multinomial Logistic Regression in Stata]]></title><link><![CDATA[http://www.baileydebarmore.com/epicode/interpreting-multinomial-logistic-regression-in-stata]]></link><comments><![CDATA[http://www.baileydebarmore.com/epicode/interpreting-multinomial-logistic-regression-in-stata#comments]]></comments><pubDate>Sun, 14 Apr 2019 17:33:53 GMT</pubDate><category><![CDATA[Stata]]></category><guid isPermaLink="false">http://www.baileydebarmore.com/epicode/interpreting-multinomial-logistic-regression-in-stata</guid><description><![CDATA[Author: Bailey DeBarmore  You may find yourself running a multinomial logistic regression, but unsure how to interpret your output. I get these questions alot from students, so I'm here to help demystify your Stata results.&nbsp;  Running the regression  To run a multinomial logistic regression, you'll use the command -mlogit-.&nbsp; You can see the code below that the syntax for the command is mlogit, followed by the outcome variable and your covariates, then a comma, and then base(#). &#8203;I [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><em><font size="1">Author: Bailey DeBarmore</font></em></div>  <div class="paragraph">You may find yourself running a multinomial logistic regression, but unsure how to interpret your output. I get these questions alot from students, so I'm here to help demystify your Stata results.&nbsp;</div>  <h2 class="wsite-content-title">Running the regression</h2>  <div class="paragraph">To run a multinomial logistic regression, you'll use the command -mlogit-.&nbsp; <br /><br />You can see the code below that the syntax for the command is mlogit, followed by the outcome variable and your covariates, then a comma, and then base(#). <br /><br />&#8203;In this example I have a 4-level variable, hypertension (htn). I want the reference category, or the base outcome, to be normal BP, which corresponds to htn=0. So I'll use base(0) in my code.&nbsp;</div>  <div>  <!--BLOG_SUMMARY_END--></div>  <blockquote>&#8203;*Analysis question:&nbsp;<br />*Estimate the association of diabetes with hypertension stage<br />*Adjusting for sex and age<br />*SYNTAX: mlogit &lt;outcome&gt; &lt;covariates&gt;, base(#)<br /><br />*the option base(#) allows you tell Stata what level of the outcome variable<br />*should be the reference - for us we'll make it htn = 0 (normal)<br />set more off<br />set line 200<br /><br />*Run the model<br /><br />mlogit htn diabetes female age, base(0)&nbsp;</blockquote>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/mlogit-output-2_orig.png" alt="Interpreting output from Stata mlogit command | EPICODE" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%">Figure 1. Stata output from running an mlogit command with a 4-level hypertension outcome, with diabetes, female sex, and age (yrs) as covariates. Each box with repeated covariates corresponds to a level of the outcome compared to the reference (which we indicated in base(#)).</div> </div></div>  <div class="wsite-spacer" style="height:50px;"></div>  <div class="paragraph">Above is the Stata output from running the mlogit command.&nbsp;<br /><br />You can see that there is a box at the top for htn=0, because we set that as the base outcome. If we had set the base outcome to be htn=2, we would have covariate output for 0, 1, and 3, and where the 2 box is, would be a blank with (base outcome).&nbsp;<br /><br />Each box corresponds to the estimated log odds of that covariate for one outcome level versus the base outcome. You can see where htn=1, it's estimating P(Elevated BP) vs P(Normal BP) (on the natural log scale).&nbsp;<br /></div>  <div class="wsite-spacer" style="height:50px;"></div>  <h2 class="wsite-content-title">The Equations</h2>  <div class="paragraph"><span>Let's connect this output with the regression equation. When I want to pull estimates, I often enter in the coefficients to an MS Excel spreadsheet, and knowing how the output translates to the equation is important.</span></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/eqns_orig.png" alt="Writing out the equation for multinomial regression | EPICODE" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%">Figure 2. How do we bring our regression output back to the statistical equation? You can write out the equation for each otucome versus the reference, here HTN = 0 or normal BP, with beta (coefficient) subscripts that correspond to the level of the outcome.</div> </div></div>  <div class="wsite-spacer" style="height:50px;"></div>  <div class="paragraph">Usually we write out the equation with just beta-0, beta-1, beta-2, etc. but since we have multiple levels of the outcome, each coefficient will be prefixed by X, which indicates the level of the variable (gray equation). I have it written out for each HTN level.&nbsp;<br /><br />Let's apply it in an example using elevated BP vs normal.<br /></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/calc-example_orig.png" alt="Example multinomial equation from mlogit in Stata | EPICODE" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%">Figure 3. Here's an example calculation where we plug in the coefficients for HTN = 1, elevated BP, into the equation we wrote out in Figure 2.</div> </div></div>  <div class="wsite-spacer" style="height:50px;"></div>  <div id="430623341864494945"><div><style type="text/css">	#element-9c33544c-b5b2-49f8-9f0f-ac0b25ca897f .colored-box-content {  clear: both;  float: left;  width: 100%;  -moz-box-sizing: border-box;  -webkit-box-sizing: border-box;  -ms-box-sizing: border-box;  box-sizing: border-box;  background-color: #f4f7f8;  padding-top: 20px;  padding-bottom: 20px;  padding-left: 20px;  padding-right: 20px;  -webkit-border-top-left-radius: 0px;  -moz-border-top-left-radius: 0px;  border-top-left-radius: 0px;  -webkit-border-top-right-radius: 0px;  -moz-border-top-right-radius: 0px;  border-top-right-radius: 0px;  -webkit-border-bottom-left-radius: 0px;  -moz-border-bottom-left-radius: 0px;  border-bottom-left-radius: 0px;  -webkit-border-bottom-right-radius: 0px;  -moz-border-bottom-right-radius: 0px;  border-bottom-right-radius: 0px;}</style><div id="element-9c33544c-b5b2-49f8-9f0f-ac0b25ca897f" data-platform-element-id="848857247979793891-1.0.1" class="platform-element-contents">	<div class="colored-box">    <div class="colored-box-content">        <div style="width: auto"><div></div><div class="paragraph"><strong>Helpful Links<br />&#8203;</strong><br />UCLA Institute for Digital Research and Education<ul><li><a href="https://stats.idre.ucla.edu/stata/output/multinomial-logistic-regression/" target="_blank">Annotated Output for Multinomial Logistic Regression in Stata</a></li><li><a href="https://stats.idre.ucla.edu/stata/dae/multinomiallogistic-regression/" target="_blank">Multinomial Logistic Regression in Stata Data Analysis Examples</a></li></ul><br />Stata Documentation for <a href="https://www.stata.com/manuals13/rmlogit.pdf" target="_blank">mlogit</a></div></div>    </div></div></div><div style="clear:both;"></div></div></div>  <h2 class="wsite-content-title">Exponentiate</h2>  <div class="paragraph">But we are really interested in the exponentiated coefficients, or the relative risk ratio in this scenario. In other Stata regression, we can use the option "or" or "exp" to transform our coefficients into the ratio. With -mlogit-, you do something a bit different - you use the option rrr in a statement run right after your regression and Stata will transform the log odds into the relative probability ratios, or the relative risk ratio (RRR).</div>  <blockquote><br />*Get exponentiated results;<br />mlogit htn diabetes female age, base(0)&nbsp;<br />mlogit,rrr<br /><br />*Is the effect of diabetes on Elevated BP vs normal BP similar for Stage 2 HTN vs normal BP?<br />test [1]diabetes = [3]diabetes</blockquote>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/mlogit-rrr_orig.png" alt="Exponentiated mlogit results in Stata | EPICODE" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%">Figure 4. To get the relative risk ratio (RRR), we run "mlogit, rrr" after running our regression. In this figure you'll see interpretations of the elevated BP vs normal BP in the grey box, and a test for the effect of diabetes in 2 outcome levels (orange box). </div> </div></div>  <div class="wsite-spacer" style="height:50px;"></div>  <div class="paragraph">The output format when we run -mlogit, rrr- is the same as before, but we have exponentiated betas.&nbsp; If you use a calculator and exponentiate the betas in the original output you'll see they match up.&nbsp;&nbsp;<br /><br />I've interpreted the RRR for elevated BP vs normal BP in the grey box.&nbsp;<br /><br />You may be interested if the effect of one covariate is the same across levels of the outcome. For example, does the effect of diabetes differ when we look at elevated BP vs normal BP versus stage 2 hypertension vs normal BP?&nbsp;<br /><br />We can use the test command and indicate the level of the outcome in [ ] 's.&nbsp;<br /><br />By writing the test statement out that the values are equal to each other, we are testing the null hypothesis that they are equal, or that their difference is zero. The prob &gt; chi2 gives us the probability of observing a more extreme chi2 value, and here our p-value of 0.16 indicates we won't be rejecting the null this time around -&gt; the effect of diabetes in elevated BP vs normal BP versus stage 2 HTN vs normal BP is similar.&nbsp;</div>  <div class="wsite-spacer" style="height:50px;"></div>  <h2 class="wsite-content-title">Marginal Probabilities</h2>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/mlogit-output_orig.png" alt="Margins Postestimation Command in MLOGIT - Stata | EPICODE" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%">Figure 5. You can estimate the predicted probability of diabetes at each level of the outcome, holding the other covariates at their means. Each box corresponds to an outcome level.</div> </div></div>  <div class="wsite-spacer" style="height:50px;"></div>  <div class="paragraph"><span>If you want to estimate the predicted probability&nbsp;of each outcome for those with adn without diabetes, you can use the margins command. You run the margins command for each level of outcome. Be sure that your factor variable of interest (diabetes in the example) is run in the regression as a factor variable (i.variable). There's usually no need to do this with binary outcomes, so you may not have. Just re-run your regression with i.variable (you can even do so 'quietly') and then run margins. Note that if you want to always run your covariates as factor variables&nbsp;(binary or categorical) you can do so. For a binary variable it will just give you 1.variable for a 0-1 variable, or you can tell Stata you want 1 to be the reference with ib1.variable.&nbsp;<br /><br /></span>With the margins command you can set each covariate to a level, such as female=1 (the average sex part here doesn't mean much) or you can predict atmeans (which is useful for age).&nbsp;</div>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <h2 class="wsite-content-title"><strong><font size="4">About the Author</font></strong></h2>  <div><div class="wsite-multicol"><div class="wsite-multicol-table-wrap" style="margin:0 -15px;"> 	<table class="wsite-multicol-table"> 		<tbody class="wsite-multicol-tbody"> 			<tr class="wsite-multicol-tr"> 				<td class="wsite-multicol-col" style="width:31.201044386423%; padding:0 15px;"> 					 						  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/ga0a1950e-r_6_orig.jpg" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>   					 				</td>				<td class="wsite-multicol-col" style="width:68.798955613577%; padding:0 15px;"> 					 						  <div class="paragraph"><span>Bailey DeBarmore is a doctoral student at the University of North Carolina at Chapel Hill studying epidemiology. Find her on Twitter&nbsp;</span><a href="https://twitter.com/BaileyDeBarmore" target="_blank">@BaileyDeBarmore</a><span>&nbsp;and blogging for the American Heart Association on the&nbsp;</span><a href="https://earlycareervoice.professional.heart.org/author/guestblogger3heart-org/" target="_blank">Early Career Voice&nbsp;</a><span>blog.&nbsp;</span><span>&#8203;&#8203;&#8203;&#8203;</span></div>   					 				</td>			</tr> 		</tbody> 	</table> </div></div></div>]]></content:encoded></item><item><title><![CDATA[Calculating IPW and SMR in SAS and Stata]]></title><link><![CDATA[http://www.baileydebarmore.com/epicode/calculating-ipw-and-smr-in-sas]]></link><comments><![CDATA[http://www.baileydebarmore.com/epicode/calculating-ipw-and-smr-in-sas#comments]]></comments><pubDate>Sun, 14 Apr 2019 12:15:45 GMT</pubDate><category><![CDATA[IPW]]></category><category><![CDATA[Regression]]></category><category><![CDATA[SAS]]></category><category><![CDATA[Stata]]></category><guid isPermaLink="false">http://www.baileydebarmore.com/epicode/calculating-ipw-and-smr-in-sas</guid><description><![CDATA[Author: Bailey DeBarmore  Learning about a method in class, like inverse probability weighting, is different than implementing it in practice.&nbsp;This post will remind you why we might be interested in propensity scores to control for confounding - specifically inverse probability of treatment weights and SMR - and then show how to do so in SAS and Stata.If you have corresponding code in R that you'd like to add to this post, please contact me.A note about weighting versus multivariable regres [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><em><font size="2">Author: Bailey DeBarmore</font></em></div>  <div class="paragraph" style="text-align:left;">Learning about a method in class, like inverse probability weighting, is different than implementing it in practice.&nbsp;<br /><br />This post will remind you why we might be interested in propensity scores to control for confounding - specifically inverse probability of treatment weights and SMR - and then show how to do so in SAS and Stata.<br /><br /><em>If you have corresponding code in R that you'd like to add to this post, please contact me.</em><br /><br /><strong>A note about weighting versus multivariable regression:</strong><br />Effect estimate interpretations when you use weighting are marginal effect in the target population. When you adjust for covariates in a regression model, you are interpreting a conditional effect, that is, the effect of the exposure holding (conditional on) the covariates being constant.&nbsp;<br /><br />Conditional estimates are troublesome with time-varying covariates because we run into collider bias and conditioning on mediators, thus weights are preferable. In simpler situations, using weights over multivariable regression can help with convergence issues .<br /><br /><strong>Files to Download:</strong><em> .txt file with SAS and Stata code, as well as a PDF version of this post with code (perfect for students) available to download at the end of the post or at <strong><a href="https://github.com/baileydebarmore/epicode.git" target="_blank">my github</a></strong></em></div>  <div class="wsite-spacer" style="height:50px;"></div>  <div>  <!--BLOG_SUMMARY_END--></div>  <h2 class="wsite-content-title"><strong>propensity scores</strong></h2>  <div class="paragraph" style="text-align:left;">A propensity score is a predicted probability that may be used to predict exposure (or treatment) status, but can also be used for censoring or missingness.&nbsp;<br /><br /><strong>How do we use propensity scores for confounding?</strong><br />We can use propensity scores to generate WEIGHTS which, when applied to the final model, make the exposure independent from confounders (Figure 1B), usually by modeling the association between the exposure and confounders (instead of the main analysis where we model the outcome and exposure).&nbsp;<br /><br />Propensity scores can also control for confounding via covariate adjustment (I discourage you from this option), stratification, and matching, in addition to weighting.<br /><br />The 2 types of weights I'll be discussing in this post are<ul><li><strong>SMR (standardized mortality/morbidity ratio) weights</strong></li><li><strong>IPTW (inverse probability of treatment weights)</strong></li></ul></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/populations_1_orig.png" alt="Creating a pseudopopulation via propensity scores | EPICODE" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%">Figure 1. Panel A shows the observed population in our data set, where the relationship between exposure and outcome (orange) is confounded by well, confounders.  In B, we have removed the arrow from confounders to exposure. We can remove the arrow in several ways, including using propensity scores (of various types) to create a pseudopopulation where the exposure and confounder are no longer associated.</div> </div></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/models_1_orig.png" alt="Prepping for IPW | EPICODE" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%">Figure 2. Panel A shows the usual multivariable model we run in our analyses - to estimate the association of the exposure with the outcome, controlled for confounders. When we want to use propensity scores, we first create the weights that we will later use in our final model by modeling the association of the confounders with the exposure - so we can remove that arrow. </div> </div></div>  <div class="wsite-spacer" style="height:50px;"></div>  <h2 class="wsite-content-title"><strong>SMR</strong></h2>  <div class="paragraph" style="text-align:left;">When you use SMR weights, you're estimating the&nbsp;<strong>average treatment effect in the treated (ATT).&nbsp;</strong>In other words, you estimate the effect had the exposed group been exposed, versus the exposed group been unexposed. The pseudopopulation that you create has a covariate (confounder) distribution equal to that observed in the exposed group.<br /><br />You can also generate your SMR weights where the unexposed group is the target of interest, and model the effect had the unexposed group been unexposed versus the unexposed group been exposed.<br /></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/smr_1_orig.png" alt="SMR with exposed and unexposed target groups | EPICODE" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%">Figure 3. In Panel A, the target group is the exposed group, so we use SMR to model had the exposed group been exposed versus unexposed, with the covariate distribution of the exposed group (yellow). In Panel B, we use the covariate distribution of the unexposed group (green), and model had unexposed group been unexposed vs exposed.</div> </div></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/smr-weights_orig.png" alt="Calculating SMR weights | EPICODE" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%">Figure 4. Equations to calculate the SMR weights for given target population corresponding to Figure 3 examples. A indicates exposure status (=1 for exposed, =0 for unexposed). The numerator is the probabilitiy of exposure given the covariate distribution of the target group, and the denominator is the probability of being assigned to what was observed. You can see that in panel B, it switches when the target group is unexposed.</div> </div></div>  <div class="wsite-spacer" style="height:50px;"></div>  <h2 class="wsite-content-title">coding SMR in SAS</h2>  <div class="paragraph">To use SMR, you'll be generating the probabilities for the numerator and denominator, and then creating the weight (numerator/denominator) and applying it in the appropriate statement.</div>  <blockquote><br /><span style="color:rgb(42, 42, 42)">***********************************************<br />* Calculating SMR weights where exposure = 0, 1<br />**************************************(********;<br /><br />&amp;let data=&lt;data&gt;;</span><br /><span style="color:rgb(42, 42, 42)">&amp;let y=&lt;outcome&gt;;</span><br /><span style="color:rgb(42, 42, 42)">&amp;let x=&lt;exposure&gt;;</span><br /><span style="color:rgb(42, 42, 42)">&amp;let id=&lt;id&gt;;</span><br /><br />*Estimate the predicted probability given covariates;<br /><br />&#8203;proc logistic data=&amp;data desc;<br />model &amp;x=&lt;covariates&gt;;<br />output out=pred p=p1;<br />run;<br /><br />*Generate the weights by exposure status, for exposed group = target their weight will be 1;<br /><br />data &lt;newdata&gt;;<br />set pred;<br />p0 = 1-p1;<br />odds = p1/p0;<br />if &amp;x=1 then wt=1;<br />else wt=odds;<br />run;<br /><br />*Final weighted analysis;<br />proc logistic data=&lt;newdata&gt; desc;<br />weight wt;<br />model &amp;y = &amp;x;<br />run;<br /><br /><br /><span style="color:rgb(42, 42, 42)">***********************************************<br />* Calculating SMR weights where exposure = categorical<br />**************************************(********;<br /><br />&amp;let data=&lt;data&gt;;</span><br /><span style="color:rgb(42, 42, 42)">&amp;let y=&lt;outcome&gt;;</span><br /><span style="color:rgb(42, 42, 42)">&amp;let x=&lt;exposure&gt;;</span><br /><span style="color:rgb(42, 42, 42)">&amp;let id=&lt;id&gt;;</span><br /><br /><span style="color:rgb(42, 42, 42)">*Estimate the predicted probability given covariates;</span><br /><br /><span style="color:rgb(42, 42, 42)">&#8203;proc logistic data=&amp;data desc;</span><br /><span style="color:rgb(42, 42, 42)">model &amp;x=&lt;covariates&gt; /LINK= glogit;</span><br /><span style="color:rgb(42, 42, 42)">output out=pred p=p1;</span><br /><span style="color:rgb(42, 42, 42)">run;</span><br /><br /><span style="color:rgb(42, 42, 42)">*Generate the weights by exposure status, for exposed group = target their weight will be 1;</span><br /><br /><span style="color:rgb(42, 42, 42)">data &lt;newdata&gt;;</span><br /><span style="color:rgb(42, 42, 42)">set pred;</span><br /><span style="color:rgb(42, 42, 42)">p0 = 1-p1;</span><br /><span style="color:rgb(42, 42, 42)">odds = p1/p0;</span><br /><span style="color:rgb(42, 42, 42)">if &amp;x=1 then wt=1;</span><br /><span style="color:rgb(42, 42, 42)">else wt=odds;</span><br /><span style="color:rgb(42, 42, 42)">run;</span><br /><br /><span style="color:rgb(42, 42, 42)">*Final weighted analysis;</span><br /><span style="color:rgb(42, 42, 42)">proc logistic data=&lt;newdata&gt; desc;</span><br /><span style="color:rgb(42, 42, 42)">weight wt;</span><br /><span style="color:rgb(42, 42, 42)">model &amp;y = &amp;x;</span><br /><span style="color:rgb(42, 42, 42)">run;</span><br /></blockquote>  <div id="963788241332910457"><div><style type="text/css">	#element-6a5531bc-ffa4-491e-8add-cbd3af0fa4bb .callout-box-wrapper {  padding: 20px 0px;  word-wrap: break-word;}#element-6a5531bc-ffa4-491e-8add-cbd3af0fa4bb .callout-box--standard {  border: 1px solid #E0E0E0;  background: #FAFAFA;  padding: 20px 20px;}#element-6a5531bc-ffa4-491e-8add-cbd3af0fa4bb .callout-box--material {  border: 1px solid #E0E0E0;  background: #FAFAFA;  padding: 20px 20px;  box-shadow: 0 0 20px rgba(0,0,0,0.15);}#element-6a5531bc-ffa4-491e-8add-cbd3af0fa4bb .callout-base {  border: 1px solid #E0E0E0;  background: #FAFAFA;  padding: 20px 20px;}#element-6a5531bc-ffa4-491e-8add-cbd3af0fa4bb .material {  box-shadow: 0 0 20px rgba(0,0,0,0.15);}</style><div id="element-6a5531bc-ffa4-491e-8add-cbd3af0fa4bb" data-platform-element-id="694046499467037623-1.2.6" class="platform-element-contents">	<div class="callout-box-wrapper">	<div class="callout-box--standard">	    <div class="element-content">	        <div style="width: auto"><div></div><div class="paragraph"><strong>What is &amp;let?</strong><br />So that you can easily adapt my code, I use &amp;let statements at the beginning of my code blocks. After the equals sign, you would replace &lt;data&gt; with your dataset name, &lt;exposure&gt; with your exposure variable, and &lt;outcome&gt; with your outcome variable. The code as written will then run with those chosen variables. Note that you do need to replace &lt;covariates&gt; in the model statement with your confounders.<br /><br />If you don't want to use &amp;let statements, simply go through the code and anywhere you see &amp;&lt;text&gt;, replace both the &amp; and the text with your regular code.</div></div>	    </div>	</div></div></div><div style="clear:both;"></div></div></div>  <h2 class="wsite-content-title">coding SMR in Stata</h2>  <div class="paragraph">The approach to calculating SMR is different in Stata. You'll be using the built in teffects command (<a href="https://www.stata.com/manuals13/te.pdf" target="_blank">reference manual [TE] here</a>) and using options to specify SMR versus IPW.&nbsp;<br /><br />Since using SMR gives us the average treatment effect in the treated, we'll use the option <strong>atet&nbsp;</strong>(average treatment effect on the treated) instead of&nbsp;<strong>ate</strong>&nbsp;(average treatment effect) which we'll use for IPTW.</div>  <blockquote><span style="color:rgb(42, 42, 42)">******************************************</span><br /><span style="color:rgb(42, 42, 42)">* Calculating SMR weights</span><br /><span style="color:rgb(42, 42, 42)">*****************************************;</span><br />&#8203;* Syntax for teffects statement<br /><br />*teffects ipw (&lt;outcome&gt;) (&lt;exposure&gt; &lt;covariates&gt;), atet<br />*where &lt;outcome&gt; is your outcome variable, &lt;exposure&gt; is your exposure variable, and &lt;covariates&gt; is a list of your covariates to generate your weights.&nbsp;<br /><br />*Example: Binary<br />*Outcome = lowbirthwt<br />*Exposure = maternalsmoke<br />*Covariates = maternalage nonwhite<br /><br />*Use the teffects statement to generate your weights and then apply them in a logistic (default) model all in 1 step<br /><br />teffects ipw (lowbirthwt) (maternalsmoke maternalage nonwhite), atet<br /><br />*If your outcome is continuous, you can specify a probit model<br /><br />*Example: Continuous<br /><span style="color:rgb(42, 42, 42)">*Outcome = birthwt</span><br /><span style="color:rgb(42, 42, 42)">*Exposure = maternalsmoke</span><br /><span style="color:rgb(42, 42, 42)">*Covariates = maternalage nonwhite<br /><br />teffects ipw (birthwt) (maternalsmoke maternalage nonwhite, probit), atet</span><br />&#8203;</blockquote>  <h2 class="wsite-content-title" style="text-align:left;"><strong>inverse probability of treatment weights (IPTW)</strong></h2>  <div class="paragraph">In contrast to SMR weights, when you use IPTW weights you are estimating the&nbsp;<strong>average treatment effect (ATE),</strong> that is the&nbsp;treatment effect in a population with covariate distribution equal to the entire observed study population, not just the exposed or unexposed.<br /><br />&#8203;Thus, you're modeling the complete counterfactual. In other words, you're estimating the effect had the entire population been exposed versus the entire population been unexposed.<br /><br />You can use unstabilized or stabilized IPTW in your final model. Choosing one over the other doesn't change your ultimate interpretation but affects the width of your confidence interval (wider when you use unstabilized).&nbsp;</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/pseudopops_2_orig.png" alt="Unstabilized vs stabilized IPW | EPICODE" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%">Figure 5. Panel A shows what happens in the pseudopopulation when we use unstabilized weights. We duplicate our N, creating 2 new populations with the covariate distribution of the entire observed population, but had everyone been exposed versus everyone unexposed. In B we apply the covariate distribution within strata of exposure, maintaining the same N. (E with a bar (macron) indicates unexposed).</div> </div></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/iptw-eq_1_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%">Figure 6. In Panel A we have the equation for unstabilized IPTW for exposed and unexposed, and in Panel B, the stabilized IPTW for exposed and unexposed. You'll see additional notes that show you that you can also calculate the weight components for unexposed by subtracting the exposed probabilities from 1. You'll see this used in our code below.</div> </div></div>  <div class="wsite-spacer" style="height:50px;"></div>  <div><div class="wsite-multicol"><div class="wsite-multicol-table-wrap" style="margin:0 -15px;"> 	<table class="wsite-multicol-table"> 		<tbody class="wsite-multicol-tbody"> 			<tr class="wsite-multicol-tr"> 				<td class="wsite-multicol-col" style="width:50%; padding:0 15px;"> 					 						  <div class="paragraph"><strong>Unstabilized</strong></div>  <div class="paragraph" style="text-align:left;">Create a pseudopopulation 2x the size of our observed - one where everyone is exposed and one where everyone is unexposed.</div>   					 				</td>				<td class="wsite-multicol-col" style="width:50%; padding:0 15px;"> 					 						  <div class="paragraph"><strong>Stabilized</strong></div>  <div class="paragraph">Create a pseudopopulation maintaining the original population size, but we adjust the covariate distribution within each strata of exposure group by upweighting and downweighting people to match the overall covariate distribution.&nbsp;</div>   					 				</td>			</tr> 		</tbody> 	</table> </div></div></div>  <div class="paragraph"><span>You can see in Figure 5 versus Figure 3 that we are using different covariate distributions. With SMR where we match the covariate distribution of the exposed or unexposed group (whichever is target). This is why IPTW generates an average treatment effect while SMR generates an average treatment effect in the treated.</span></div>  <h2 class="wsite-content-title">coding IPTW in SAS</h2>  <blockquote><span style="color:rgb(42, 42, 42)">******************************************</span><br /><span style="color:rgb(42, 42, 42)">* Calculating IPTW</span><br /><span style="color:rgb(42, 42, 42)">*****************************************;<br />&#8203;</span><br />&amp;let data=&lt;data&gt;;<br />&amp;let y=&lt;outcome&gt;;<br />&amp;let x=&lt;exposure&gt;;<br />&amp;let id=&lt;id&gt;;<br /><br />*Estimate denominator - output a dataset with results of regression called denom, with the resulting probabilities stored in variable d;<br />&#8203;<br />proc logistic data=&amp;data desc;<br />model &amp;x = &lt;covariates&gt;;<br />output out=denom p=d;<br />run;<br /><br />*Generate numerator for stabilized weights - output a dataset with results of regression called num, with the resulting probabilities stored in variable n - note that there is nothing on the right side of the equation because the numerator will simply be P(A=a), where a = observed exposure status;<br /><br />proc logistic data=&amp;data desc;<br />model &amp;x=;<br />output out=num p=n;<br />run;<br /><br />*Generate stabilized and unstabilized weights by merging the datasets with regression output (merge on the unique identifier in your dataset, &amp;id);<br /><br />data &lt;newdata&gt;;<br />merge &amp;data denom num;<br />by &amp;id;<br />if &amp;x=1 then do;<br />uw = 1/d;&nbsp;<br />sw = n/d;<br />end;<br /><br />*Remember we can use 1 - P(exposed) for the unexposed weight components;<br />&#8203;<br />else if &amp;x=0 then do;<br />uw=1/(1-d);<br />sw=(1-n)/(1-d);<br />end;<br />&#8203;run;<br /><br />*Check the distribution of your IPTW - the mean should be 1. Is the sum for uw twice the sum of sw? why? is the range of uw greater than sw? why?;<br /><br />proc means data=&lt;newdata&gt; mean sum min max;<br />var uw sw;<br />run;<br /><br />*You can check to see if your exposure and covariates are associated in your new pseudopopulation (&lt;newdata&gt;);<br /><br />proc logistic data=&lt;newdata&gt; desc;<br />weight sw;<br />model &amp;x=&lt;covariates&gt;;<br />run;<br /><br />*Now you can run your main analyses and apply the weights using the weight statement - use sw variable for stabilized weights, and use uw for unstabilized weights - you can use proc genmod, glm, logistic, etc. I'll show you below with logistic you can see now we're using &amp;y and &amp;x - and we don't need the covariates because the confounder -&gt; x arrow is encompassed in the sw weight statement;<br /><br />proc logistic data=&lt;newdata&gt; desc;<br />weight sw;<br />model &amp;y = &amp;x;<br />run;</blockquote>  <h2 class="wsite-content-title">coding IPTW in Stata</h2>  <div class="paragraph"><span>The approach to calculating IPTW is different in Stata than SAS. You'll be using the built in teffects command (</span><a href="https://www.stata.com/manuals13/te.pdf" target="_blank">reference manual [TE] here</a><span>) and using options to specify IPTW.</span><br /><br /><span>Since using IPTW results in the average treatment effect overall, we'll use option&nbsp;<strong>ate</strong>&nbsp;(average treatment effect) instead of&nbsp;&nbsp;option&nbsp;</span><strong>atet&nbsp;</strong><span>(average treatment effect on the treated) that we use for SMR.&nbsp;</span></div>  <blockquote><span style="color:rgb(42, 42, 42)">******************************************</span><br /><span style="color:rgb(42, 42, 42)">* Calculating IPTW</span><br /><span style="color:rgb(42, 42, 42)">*****************************************;<br />&#8203;<br />&#8203;* Syntax for teffects statement</span><br /><br /><span style="color:rgb(42, 42, 42)">*teffects ipw (&lt;outcome&gt;) (&lt;exposure&gt; &lt;covariates&gt;), ate</span><br /><span style="color:rgb(42, 42, 42)">*where &lt;outcome&gt; is your outcome variable, &lt;exposure&gt; is your exposure variable, and &lt;covariates&gt; is a list of your covariates to generate your weights.&nbsp;</span><br /><br /><span style="color:rgb(42, 42, 42)">*Example: Binary</span><br /><span style="color:rgb(42, 42, 42)">*Outcome = lowbirthwt</span><br /><span style="color:rgb(42, 42, 42)">*Exposure = maternalsmoke</span><br /><span style="color:rgb(42, 42, 42)">*Covariates = maternalage nonwhite</span><br /><br /><span style="color:rgb(42, 42, 42)">*Use the teffects statement to generate your weights and then apply them in a logistic (default) model all in 1 step</span><br /><br /><span style="color:rgb(42, 42, 42)">teffects ipw (lowbirthwt) (maternalsmoke maternalage nonwhite), ate</span><br /><br /><span style="color:rgb(42, 42, 42)">*If your outcome is continuous, you can specify a probit model</span><br /><br /><span style="color:rgb(42, 42, 42)">*Example: Continuous</span><br /><span style="color:rgb(42, 42, 42)">*Outcome = birthwt</span><br /><span style="color:rgb(42, 42, 42)">*Exposure = maternalsmoke</span><br /><span style="color:rgb(42, 42, 42)">*Covariates = maternalage nonwhite<br /><br />teffects ipw (birthwt) (maternalsmoke maternalage nonwhite, probit), ate</span><br /><br />* Syntax to manually create IPTW for binary exposure (treatment)<br />logistic treatment vars<br />predict p<br />gen iptw = 1/p if treatment==1<br />replace iptw=1/(1-p) if treatment==0<br /><br />*To calculate stabilized IPTW, run tab treatment and use the proportions for X below<br />tab treatment<br />gen siptw = X/p if treatment==1<br />replace siptw = (1-X)/(1-p) if treatment==0<br /><br /></blockquote>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <div class="paragraph" style="text-align:left;">UPDATE: Feb 22 2021<br />If your treatment (exposure) is&nbsp;<strong>categorical</strong>&nbsp;you'll need to change things up a bit. I'm writing this blurb in response to a comment below, and in response to this topic coming up several times in just the past week!&nbsp;<br /></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/cat-iptw_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%">Figure 7. Calculating IPTW for a categorical A.</div> </div></div>  <div class="paragraph" style="text-align:left;">&#8203;<span>In your software of choice, you need to calculate the probability of being treated given your covariates, save those probabilities, and then assign the probability given each observations observed status.</span><br /><br /><span>In SAS, you can use code like the sample below (thanks, Paul!) which uses a generalized logit model for a treatment variable &lt;treatment&gt; with multiple categories.&nbsp;</span><br /><br /><span>The output data set will have probabilities for every value of treatment. For example, a person with treatment=1 will have values for treatment=0,1,2,3 so you need to do some more coding to tell the computer you only want the predicted value for treatment if treatment=treatment.</span></div>  <blockquote>&#8203;PROC LOGISTIC DATA=...;<br />&nbsp;&nbsp;&nbsp; MODEL treatment = vars / LINK=glogit;<br />&nbsp;&nbsp;&nbsp; OUTPUT OUT=denom_ipw P=d;<br />RUN;<br /></blockquote>  <div class="paragraph">In Stata, you can run mlogit to estimate the probability of &lt;treatment&gt; adjusted for variables &lt;vars&gt; and then use the postestimation commands, predict, to create a denominator variable for each value of treatment (0, 1, 2, 3). You use the option "outcome" to tell Stata this.&nbsp;</div>  <blockquote>mlogit treatment vars<br />predict p0, outcome(0)<br />predict p1, outcome(1)<br />predict p2, outcome(2)<br />predict p3, outcome(3)</blockquote>  <div class="paragraph">Then create your weight variable, iptw below.</div>  <blockquote>gen iptw=.<br />replace iptw=1/p0 if treatment==0<br />replace iptw=1/p1 if treatment==1<br />replace iptw=1/p2 if treatment==2<br />replace iptw=1/p3 if treatment==3</blockquote>  <div class="paragraph">If you want to create stabilized weights, you can run a tab to get the proportion in each category, and then calculate your weights. For example, let's say my groups are distributed as P(A=0)=0.6, P(A=1)=0.14, P(A=2)=0.2, and P(A=3)=0.06, I would make a stabilized iptw variable, siptw, below.</div>  <blockquote>gen siptw=.<br />replace siptw=0.6/p0 if treatment==0<br /><span style="color:rgb(42, 42, 42)">replace siptw=0.14/p1 if treatment==1</span><br /><span style="color:rgb(42, 42, 42)">replace siptw=0.2/p2 if treatment==2</span><br /><span style="color:rgb(42, 42, 42)">replace siptw=0.06/p3 if treatment==3</span></blockquote>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <div class="paragraph">Download resources here, or get the most up-to-date versions on <strong><a href="https://github.com/baileydebarmore/epicode.git" target="_blank" title="">my GitHub</a></strong></div>  <div><div style="margin: 10px 0 0 -10px"> <a title="Download file: Calculating SMR and IPW - SAS - 2021 - EPICODE" href="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/calculatingsmrandipwepicode_sas_2021.txt"><img src="//www.weebly.com/weebly/images/file_icons/txt.png" width="36" height="36" style="float: left; position: relative; left: 0px; top: 0px; margin: 0 15px 15px 0; border: 0;" /></a><div style="float: left; text-align: left; position: relative;"><table style="font-size: 12px; font-family: tahoma; line-height: .9;"><tr><td colspan="2"><b> Calculating SMR and IPW - SAS - 2021 - EPICODE</b></td></tr><tr style="display: none;"><td>File Size:  </td><td>8 kb</td></tr><tr style="display: none;"><td>File Type:  </td><td> txt</td></tr></table><a title="Download file: Calculating SMR and IPW - SAS - 2021 - EPICODE" href="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/calculatingsmrandipwepicode_sas_2021.txt" style="font-weight: bold;">Download File</a></div> </div>  <hr style="clear: both; width: 100%; visibility: hidden"></hr></div>  <div><div style="margin: 10px 0 0 -10px"> <a title="Download file: Calculating SMR and IPW in Stata - 2022" href="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/calculatingsmrandipwepicode_stata_2022.txt"><img src="//www.weebly.com/weebly/images/file_icons/txt.png" width="36" height="36" style="float: left; position: relative; left: 0px; top: 0px; margin: 0 15px 15px 0; border: 0;" /></a><div style="float: left; text-align: left; position: relative;"><table style="font-size: 12px; font-family: tahoma; line-height: .9;"><tr><td colspan="2"><b> Calculating SMR and IPW in Stata - 2022</b></td></tr><tr style="display: none;"><td>File Size:  </td><td>6 kb</td></tr><tr style="display: none;"><td>File Type:  </td><td> txt</td></tr></table><a title="Download file: Calculating SMR and IPW in Stata - 2022" href="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/calculatingsmrandipwepicode_stata_2022.txt" style="font-weight: bold;">Download File</a></div> </div>  <hr style="clear: both; width: 100%; visibility: hidden"></hr></div>  <div><div style="margin: 10px 0 0 -10px"> <a title="Download file: Coding IPW and SMR in SAS and Stata - PDF for teachers" href="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/coding_ipw_and_smr_in_sas_and_stata-pdf.pdf"><img src="//www.weebly.com/weebly/images/file_icons/pdf.png" width="36" height="36" style="float: left; position: relative; left: 0px; top: 0px; margin: 0 15px 15px 0; border: 0;" /></a><div style="float: left; text-align: left; position: relative;"><table style="font-size: 12px; font-family: tahoma; line-height: .9;"><tr><td colspan="2"><b> Coding IPW and SMR in SAS and Stata - PDF for teachers</b></td></tr><tr style="display: none;"><td>File Size:  </td><td>551 kb</td></tr><tr style="display: none;"><td>File Type:  </td><td> pdf</td></tr></table><a title="Download file: Coding IPW and SMR in SAS and Stata - PDF for teachers" href="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/coding_ipw_and_smr_in_sas_and_stata-pdf.pdf" style="font-weight: bold;">Download File</a></div> </div>  <hr style="clear: both; width: 100%; visibility: hidden"></hr></div>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <div id="980172483574519641"><div><style type="text/css">	#element-27c0c07d-27c8-4a8f-a7bb-0f30c647ed53 .colored-box-content {  clear: both;  float: left;  width: 100%;  -moz-box-sizing: border-box;  -webkit-box-sizing: border-box;  -ms-box-sizing: border-box;  box-sizing: border-box;  background-color: #f4f7f8;  padding-top: 20px;  padding-bottom: 20px;  padding-left: 20px;  padding-right: 20px;  -webkit-border-top-left-radius: 0px;  -moz-border-top-left-radius: 0px;  border-top-left-radius: 0px;  -webkit-border-top-right-radius: 0px;  -moz-border-top-right-radius: 0px;  border-top-right-radius: 0px;  -webkit-border-bottom-left-radius: 0px;  -moz-border-bottom-left-radius: 0px;  border-bottom-left-radius: 0px;  -webkit-border-bottom-right-radius: 0px;  -moz-border-bottom-right-radius: 0px;  border-bottom-right-radius: 0px;}</style><div id="element-27c0c07d-27c8-4a8f-a7bb-0f30c647ed53" data-platform-element-id="848857247979793891-1.0.1" class="platform-element-contents">	<div class="colored-box">    <div class="colored-box-content">        <div style="width: auto"><div></div><h2 class="wsite-content-title">Suggested citation</h2><div class="paragraph" style="text-align:left;">DeBarmore BM. &ldquo;Coding IPW and SMR in SAS and Stata&rdquo;. 2019. Updated 2021. Retrieved from <a href="http://www.baileydebarmore.com/epicode/calculating-ipw-and-smr-in-sas">http://www.baileydebarmore.com/epicode/calculating-ipw-and-smr-in-sas</a><br /></div></div>    </div></div></div><div style="clear:both;"></div></div></div>  <h2 class="wsite-content-title"><strong><font size="3">About the author</font></strong></h2>  <div><div class="wsite-multicol"><div class="wsite-multicol-table-wrap" style="margin:0 -15px;"> 	<table class="wsite-multicol-table"> 		<tbody class="wsite-multicol-tbody"> 			<tr class="wsite-multicol-tr"> 				<td class="wsite-multicol-col" style="width:31.201044386423%; padding:0 15px;"> 					 						  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/ga0a1950_orig.jpg" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>   					 				</td>				<td class="wsite-multicol-col" style="width:68.798955613577%; padding:0 15px;"> 					 						  <div class="paragraph" style="text-align:left;"><span>Bailey DeBarmore is a doctoral student at the University of North Carolina at Chapel Hill studying epidemiology. Find her on Twitter&nbsp;</span><a href="https://twitter.com/BaileyDeBarmore" target="_blank">@BaileyDeBarmore</a><span>&nbsp;and blogging for the American Heart Association on the&nbsp;</span><a href="https://earlycareervoice.professional.heart.org/author/guestblogger3heart-org/" target="_blank">Early Career Voice&nbsp;</a><span>blog.&nbsp;</span><span>&#8203;&#8203;&#8203;</span></div>   					 				</td>			</tr> 		</tbody> 	</table> </div></div></div>]]></content:encoded></item><item><title><![CDATA[How to Make Publication Quality Graphs in Excel]]></title><link><![CDATA[http://www.baileydebarmore.com/epicode/how-to-make-publication-quality-graphs-in-excel]]></link><comments><![CDATA[http://www.baileydebarmore.com/epicode/how-to-make-publication-quality-graphs-in-excel#comments]]></comments><pubDate>Sun, 16 Sep 2018 12:42:21 GMT</pubDate><category><![CDATA[Bailey DeBarmore]]></category><category><![CDATA[Data Visualization]]></category><category><![CDATA[Excel]]></category><guid isPermaLink="false">http://www.baileydebarmore.com/epicode/how-to-make-publication-quality-graphs-in-excel</guid><description><![CDATA[           Learning to clean your data and run the appropriate statistical tests in your program of choice is challenge enough. When it comes to producing graphs for your posters and publications, it can be frustrating to learn how to code to get exactly the graph you want.&nbsp;Using Microsoft Excel to produce graphs can open up a whole new world for you. Easily organizing your data from columns to rows, adjusting categories and axes in real-time can streamline the entire process.&nbsp;While th [...] ]]></description><content:encoded><![CDATA[<div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/editor/how-to-make-publication-quality-graphs-in-excel_1.png?1537104765" alt="How to Make Publication Quality Graphs in MS Excel - EPICODE - Bailey DeBarmore" style="width:524;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div>  <!--BLOG_SUMMARY_END--></div>  <div class="paragraph" style="text-align:left;">Learning to clean your data and run the appropriate statistical tests in your program of choice is challenge enough. When it comes to producing graphs for your posters and publications, it can be frustrating to learn how to code to get exactly the graph you want.&nbsp;<br /><br />Using Microsoft Excel to produce graphs can open up a whole new world for you. Easily organizing your data from columns to rows, adjusting categories and axes in real-time can streamline the entire process.&nbsp;<br /><br />While the default figures left much to be desired, this post will summarize several ways to strategically change the aesthetics to create publication quality graphics.&#8203;</div>  <div id="906197078955458756"><div><style type="text/css">	#element-32a5f124-1314-46f3-9124-ee0ea573db0a .callout-box-wrapper {  padding: 20px 0px;  word-wrap: break-word;}#element-32a5f124-1314-46f3-9124-ee0ea573db0a .callout-box--standard {  border: 1px solid #E0E0E0;  background: #FAFAFA;  padding: 20px 20px;}#element-32a5f124-1314-46f3-9124-ee0ea573db0a .callout-box--material {  border: 1px solid #E0E0E0;  background: #FAFAFA;  padding: 20px 20px;  box-shadow: 0 0 20px rgba(0,0,0,0.15);}#element-32a5f124-1314-46f3-9124-ee0ea573db0a .callout-base {  border: 1px solid #E0E0E0;  background: #FAFAFA;  padding: 20px 20px;}#element-32a5f124-1314-46f3-9124-ee0ea573db0a .material {  box-shadow: 0 0 20px rgba(0,0,0,0.15);}</style><div id="element-32a5f124-1314-46f3-9124-ee0ea573db0a" data-platform-element-id="694046499467037623-1.2.6" class="platform-element-contents">	<div class="callout-box-wrapper">	<div class="callout-box--standard">	    <div class="element-content">	        <div style="width: auto"><div></div><div class="paragraph" style="text-align:left;">For details on how to transform your Excel graphs from lackluster to publication-read, download the PDF below</div><div style="text-align:center;"><div style="height: 10px; overflow: hidden;"></div><a class="wsite-button wsite-button-small wsite-button-highlight" href="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/how_to_make_publication_quality_graphs_in_excel_-_epicode_-_bailey_debarmore.pdf" target="_blank"><span class="wsite-button-inner">download</span></a><div style="height: 10px; overflow: hidden;"></div></div></div>	    </div>	</div></div></div><div style="clear:both;"></div></div></div>  <h2 class="wsite-content-title">summary</h2>  <div class="paragraph"><ol><li>Make sure your data is in the right format for inserting a chart</li><li>Change font from default Calibri to Arial, and change all font from gray to black</li><li>Add X- and Y-axes lines in black</li><li>Add axis titles</li><li>Change colors and patterns of graph for optimal design</li></ol><br />Optional<br /><ul><li>Add secondary Y-axis if needed</li><li>Change units if needed</li></ul></div>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <h2 class="wsite-content-title"><strong><font size="4">About the Author</font></strong></h2>  <div><div class="wsite-multicol"><div class="wsite-multicol-table-wrap" style="margin:0 -15px;"> 	<table class="wsite-multicol-table"> 		<tbody class="wsite-multicol-tbody"> 			<tr class="wsite-multicol-tr"> 				<td class="wsite-multicol-col" style="width:31.201044386423%; padding:0 15px;"> 					 						  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/ga0a1950e-r_5_orig.jpg" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>   					 				</td>				<td class="wsite-multicol-col" style="width:68.798955613577%; padding:0 15px;"> 					 						  <div class="paragraph" style="text-align:left;"><span>Bailey DeBarmore is a doctoral student at the University of North Carolina at Chapel Hill studying epidemiology. Find her on Twitter</span><a href="https://twitter.com/BaileyDeBarmore" target="_blank">@BaileyDeBarmore</a><span>&nbsp;and blogging for the American Heart Association on the&nbsp;</span><a href="https://earlycareervoice.professional.heart.org/author/guestblogger3heart-org/" target="_blank">Early Career Voice&nbsp;</a><span>blog.&nbsp;</span><span>&#8203;&#8203;</span></div>   					 				</td>			</tr> 		</tbody> 	</table> </div></div></div>]]></content:encoded></item><item><title><![CDATA[Modeling Categorical Predictors in SAS]]></title><link><![CDATA[http://www.baileydebarmore.com/epicode/modeling-categorical-predictors-in-sas]]></link><comments><![CDATA[http://www.baileydebarmore.com/epicode/modeling-categorical-predictors-in-sas#comments]]></comments><pubDate>Sat, 25 Aug 2018 22:04:52 GMT</pubDate><category><![CDATA[Bailey DeBarmore]]></category><category><![CDATA[Regression]]></category><category><![CDATA[SAS]]></category><guid isPermaLink="false">http://www.baileydebarmore.com/epicode/modeling-categorical-predictors-in-sas</guid><description><![CDATA[Trying to figure out how to model a categorical predictor in your regression?&nbsp;Done this code a million times but can never remember the syntax for the class statement?&nbsp;Want to generate exponentiated estimates and confidence intervals?We'll give examples for binary, 3 levels, 4 levels, and stratified.      Binary Predictor  For all of these code snippets, define &amp;data, &amp;outcome, and &amp;var with your data set, outcome variable, and predictor variable.  &amp;let data=&lt;dataset [...] ]]></description><content:encoded><![CDATA[<div class="paragraph">Trying to figure out how to model a categorical predictor in your regression?&nbsp;<br /><br />Done this code a million times but can never remember the syntax for the class statement?&nbsp;<br /><br />Want to generate exponentiated estimates and confidence intervals?<br /><br />We'll give examples for binary, 3 levels, 4 levels, and stratified.<br /></div>  <div>  <!--BLOG_SUMMARY_END--></div>  <h2 class="wsite-content-title">Binary Predictor</h2>  <div class="paragraph">For all of these code snippets, define &amp;data, &amp;outcome, and &amp;var with your data set, outcome variable, and predictor variable.</div>  <blockquote>&amp;let data=&lt;dataset&gt;;<br />&amp;let outcome=&lt;outcome&gt;;<br />&#8203;&amp;let var=&lt;var&gt;;<br /></blockquote>  <div class="paragraph">Here we've used proc genmod, and called on logistic regression using the logit link and binomial distribution.<br /><br />The estimate statement puts a value of 1 in for the predictor variable. The "exp" option has SAS exponentiate the OR and 95% CI for us. You'll want to go to the row labeled Exp(&amp;VAR), over to the estimate and 95% CI column.<br /></div>  <blockquote>&#8203;<strong>proc</strong> <strong>genmod</strong> data=&amp;data descending;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; model &amp;outcome = &amp;var / link=logit dist=binomial type3;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; estimate "&amp;var" &amp;var <strong>1</strong> / exp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>run</strong>;</blockquote>  <h2 class="wsite-content-title">Multi-Level Categorical Predictor</h2>  <div class="paragraph">This example is for an age category variable, which can easily have more than 3 or 4 levels. Here, &amp;var is "agecat", and the reference value is the youngest age group, 18-29. You'd need to replace the estimate "OR LABEL" &amp;var... statement with your own labels.<br /><br />The tricky part here is how many zeros? You can see for each subsequent level, we add a zero, extending the 1 out. You'll see later even when we make the reference value a different level, it's similar.<br /></div>  <blockquote>&nbsp;<strong>proc</strong> <strong>genmod</strong> data=&amp;data descending;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class &amp;var (ref='1') / param=ref;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; model &amp;outcome = &amp;var / link=logit dist=binomial type3;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; estimate "OR 30-39" &amp;var&nbsp;<strong>1</strong> / exp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; estimate "OR 40-49" &amp;var&nbsp;<strong>0</strong> <strong>1</strong> / exp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; estimate "OR 50-59" &amp;var&nbsp;<strong>0</strong> <strong>0</strong> <strong>1</strong> / exp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; estimate "OR 60-69" &amp;var&nbsp;<strong>0</strong> <strong>0</strong> <strong>0</strong> <strong>1</strong> / exp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; estimate "OR 70-79" &amp;var&nbsp;<strong>0</strong> <strong>0</strong> <strong>0</strong> <strong>0</strong> <strong>1</strong> / exp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; estimate "OR 80+" &amp;var&nbsp;&nbsp;<strong>0</strong> <strong>0</strong> <strong>0</strong> <strong>0</strong> <strong>0</strong> <strong>1</strong> / exp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>run</strong>;<br /><br /></blockquote>  <h2 class="wsite-content-title">Different Reference Value</h2>  <div class="paragraph">This variable has 3 levels. We're choosing level 2 (private insurance), to be the reference. You can see that when we do our estimate statement, we don't skip over 0 1 for level 2, but instead go sequentially like in the last example.&nbsp;<br /><br />If instead we made the reference level 3, we would adjust our labels to reflect that, and use the same 1 and 0 1 designation in the estimate statements.<br /></div>  <blockquote><strong>proc</strong> <strong>genmod</strong> data=out.cohort6 descending;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class &amp;var (ref='2') / param=ref;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; model &amp;outcome = &amp;var / link=logit dist=binomial;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; estimate "OR Public" &amp;var&nbsp;<strong>1</strong> / exp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; estimate "OR Other" &amp;var&nbsp;<strong>0</strong> <strong>1</strong> / exp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>run</strong>;<br /></blockquote>  <h2 class="wsite-content-title">Stratified Logistic Regression with Categorical Predictors</h2>  <div class="paragraph">What if you want to stratify? First, sort your data set by the strata variable. Then run your analyses as above, but add a -by- statement.<br /><br />Your output will be for strata=0 and strata=1 (or more if you have more levels). You won't get an overall output, so you'll need to run that separately.<br /></div>  <blockquote><strong>proc</strong> <strong>sort</strong> data=&amp;data out=sort;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by &amp;strata;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>run</strong>;<br />&nbsp;<br /><strong>proc</strong> <strong>genmod</strong> data=sort descending;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by &amp;strata;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class &amp;var&nbsp; (ref='1') / param=ref;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; model &amp;outcome = &amp;var / link=logit dist=binomial type3;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; estimate "OR q2" &amp;var&nbsp;&nbsp;<strong>1</strong> / exp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; estimate "OR q3" &amp;var&nbsp;<strong>0</strong> <strong>1</strong>/ exp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; estimate "OR q4" &amp;var&nbsp;&nbsp;<strong>0</strong> <strong>0</strong> <strong>1</strong> / exp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>run</strong>;<br /></blockquote>  <div class="paragraph">Enjoy! Feel free to bookmark.&nbsp;</div>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <h2 class="wsite-content-title"><strong><font size="4">About the Author</font></strong></h2>  <div><div class="wsite-multicol"><div class="wsite-multicol-table-wrap" style="margin:0 -15px;"> 	<table class="wsite-multicol-table"> 		<tbody class="wsite-multicol-tbody"> 			<tr class="wsite-multicol-tr"> 				<td class="wsite-multicol-col" style="width:24.444444444444%; padding:0 15px;"> 					 						  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/ga0a1950e-r_4_orig.jpg" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>   					 				</td>				<td class="wsite-multicol-col" style="width:75.555555555556%; padding:0 15px;"> 					 						  <div class="paragraph"><span>Bailey DeBarmore is a doctoral student at the University of North Carolina at Chapel Hill studying epidemiology. Find her on Twitter</span><a href="https://twitter.com/BaileyDeBarmore" target="_blank">@BaileyDeBarmore</a><span>&nbsp;and blogging for the American Heart Association on the&nbsp;</span><a href="https://earlycareervoice.professional.heart.org/author/guestblogger3heart-org/" target="_blank">Early Career Voice&nbsp;</a><span>blog.&nbsp;</span>&#8203;</div>   					 				</td>			</tr> 		</tbody> 	</table> </div></div></div>]]></content:encoded></item><item><title><![CDATA[zEpid: a Python library for epidemiology tools]]></title><link><![CDATA[http://www.baileydebarmore.com/epicode/zepid-a-python-library-for-epidemiology-tools]]></link><comments><![CDATA[http://www.baileydebarmore.com/epicode/zepid-a-python-library-for-epidemiology-tools#comments]]></comments><pubDate>Sun, 08 Jul 2018 01:08:48 GMT</pubDate><category><![CDATA[Paul Zivich]]></category><category><![CDATA[Python]]></category><category><![CDATA[zEpid]]></category><guid isPermaLink="false">http://www.baileydebarmore.com/epicode/zepid-a-python-library-for-epidemiology-tools</guid><description><![CDATA[Author: Paul Zivich  Python is a general computer programming language but has recently garnered popularity among data scientists with its versatility, ability to quickly process large data sets, and large library of machine learning models. I taught myself Python two years ago and while there are several Python libraries for epidemiology, I found the libraries were no longer actively maintained, did not interact with pandas (the main data management Python library), or implement causal inferenc [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><em><font size="2">Author: Paul Zivich</font></em></div>  <div class="paragraph">Python is a general computer programming language but has recently garnered popularity among data scientists with its versatility, ability to quickly process large data sets, and large library of machine learning models. I taught myself Python two years ago and while there are several Python libraries for epidemiology, I found the libraries were no longer actively maintained, did not interact with pandas (the main data management Python library), or implement causal inference methods (like inverse probability weights). To fill this gap, I created zEpid with the goal of making epidemiologic analyses in Python e-z.</div>  <div>  <!--BLOG_SUMMARY_END--></div>  <h2 class="wsite-content-title"><strong><font size="4">Functional Form Assessment</font></strong></h2>  <div class="paragraph"><span>I have a few features that I especially like and will highlight them here. First is the functional form assessment. I always found coding functional form assessments to be tedious and difficult to obtain a nice-looking plot from SAS. The code I wrote creates a functional form plot and prints the model results. Below is a fully contained example</span></div>  <blockquote>&#8203;import zepid as ze<br />import matplotlib.pyplot as plt<br />df = ze.load_sample_data(timevary=False)<br />ze.graphics.func_form_plot(df,outcome='dead',var='age0',discrete=True)<br />plt.show()</blockquote>  <div class="paragraph">&#8203;<br />&#8203;Which gives the following output:</div>  <blockquote>&#8203;Warning: missing observations of model variables are dropped&nbsp;<br />0&nbsp; observations were dropped from the functional form assessment<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Generalized Linear Model Regression Results<br />==============================================================================<br />Dep. Variable:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dead&nbsp;&nbsp; No. Observations:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 547<br />Model:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GLM&nbsp;&nbsp; Df Residuals:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 545<br />Model Family:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Binomial&nbsp;&nbsp; Df Model:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<br />Link Function:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logit&nbsp;&nbsp; Scale:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.0000<br />Method:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IRLS&nbsp;&nbsp; Log-Likelihood:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -239.25<br />Date:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Tue, 26 Jun 2018&nbsp;&nbsp; Deviance:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 478.51<br />Time:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 08:25:47&nbsp;&nbsp; Pearson chi2:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 553.<br />No. Iterations:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp; Covariance Type:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nonrobust<br />==============================================================================<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; coef&nbsp;&nbsp;&nbsp; std err&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; z&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; P&gt;|z|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [0.025&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.975]<br />------------------------------------------------------------------------------<br />Intercept&nbsp;&nbsp;&nbsp;&nbsp; -3.6271&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.537&nbsp;&nbsp;&nbsp;&nbsp; -6.760&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -4.679&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -2.575<br />age0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0507&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.012&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.075<br />==============================================================================<br />AIC:&nbsp; 482.50783872152573<br />BIC:&nbsp; -2957.4167585984537<br /></blockquote>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/published/spline1.png?1531013750" alt="zEpid - a Python library for epidemiology tools" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <h2 class="wsite-content-title"><strong><font size="4">Generate Splines</font></strong></h2>  <div class="paragraph">Assessing other functional forms, creating splines, and adding points which correspond to groups of observations are also easily implementable. Since I mentioned splines, zEpid also has easy to use functionality to generate splines. The following line of code will generate a restricted quadratic spline with knots at 30, 40, and 55. Continuing with the functional form plot code from previous, we can generate another functional form plot</div>  <blockquote>&#8203;df[['rqs0','rqs1']] = ze.spline(df,var='age0',n_knots=3,knots=[30,40,50],restricted=True)<br />ze.graphics.func_form_plot(df,outcome='dead',var='age0',f_form='age0 + rqs0 + rqs1',discrete=True)<br />plt.vlines(30,0,0.85,colors='gray',linestyles='--')<br />plt.vlines(40,0,0.85,colors='gray',linestyles='--')<br />plt.vlines(55,0,0.85,colors='gray',linestyles='--')<br />plt.show()<br /></blockquote>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/editor/spline2.png?1531013724" alt="zEpid - a Python library for epidemiology tools" style="width:531;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <h2 class="wsite-content-title"><strong><font size="4">Inverse Probability Weights</font></strong></h2>  <div class="paragraph">&#8203;Lastly, zEpid has functionalities for inverse probability weights. Currently, inverse probability of treatment weights, inverse probability of censoring weights, and inverse probability of missing weights are implemented. The following block of code can be used to fit a time-fixed IPTW model. Note that we will use statsmodels to obtain the final result. Currently, zEpid only generates the weights to maintain user functionality (i.e. ability to manipulate weights for a marginal structural model).<br /></div>  <blockquote>&#8203;#Loading necessary packages to fit model<br />import zepid as ze<br />import statsmodels.api as sm<br />import statsmodels.formula.api as smf<br />from statsmodels.genmod.families import family,links<br />&nbsp;<br />#Loading the example data within zEpid<br />df = ze.load_sample_data(timevary=False)<br />&nbsp;<br />#Creating polynomial terms<br />df['cd40sq'] = df['cd40']**2<br />df['cd40cu'] = df['cd40']**3<br />&nbsp;<br />#Generating stabilized IPTW for ART as exposure<br />model = 'male + age0 + cd40 + cd40sq + cd40cu + dvl0'<br />df['iptw'] = ze.ipw.iptw(df,treatment='art',model_denominator=model,stabilized=True)<br />&nbsp;<br />#Fitting a GEE model with the statsmodels library to obtain the risk of death by ART exposure (Risk Difference)<br />ind = sm.cov_struct.Independence() <br />f = sm.families.family.Binomial(sm.families.links.identity)<br />linrisk = smf.gee('dead ~ art',df['id'],df,cov_struct=ind,family=f,weights=df['iptw']).fit()<br />print(linrisk.summary())</blockquote>  <div class="paragraph"><br />&#8203;Which gives us the following results</div>  <blockquote>&#8203;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GEE Regression Results<br />===================================================================================<br />Dep. Variable:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dead&nbsp;&nbsp; No. Observations:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 547<br />Model:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GEE&nbsp;&nbsp; No. clusters:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 547<br />Method:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Generalized&nbsp;&nbsp; Min. cluster size:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Estimating Equations&nbsp;&nbsp; Max. cluster size:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<br />Family:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Binomial&nbsp;&nbsp; Mean cluster size:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.0<br />Dependence structure:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Independence&nbsp;&nbsp; Num. iterations:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<br />Date:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Tue, 26 Jun 2018&nbsp;&nbsp; Scale:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.000<br />Covariance type:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; robust&nbsp;&nbsp; Time:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13:56:22<br />==============================================================================<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; coef&nbsp;&nbsp;&nbsp; std err&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; z&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; P&gt;|z|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [0.025&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.975]<br />------------------------------------------------------------------------------<br />Intercept&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.1817&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.018&nbsp;&nbsp;&nbsp;&nbsp; 10.008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.146&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.217<br />art&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -0.0826&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.037&nbsp;&nbsp;&nbsp;&nbsp; -2.205&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -0.156&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -0.009<br />==============================================================================<br />Skew:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.7574&nbsp;&nbsp; Kurtosis:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.1278<br />Centered skew:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0000&nbsp;&nbsp; Centered kurtosis:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -3.0000<br />==============================================================================</blockquote>  <div class="paragraph">You can visit the following website for a description on fitting a marginal structural model with an inverse probability weighted Kaplan Meier:<br /><a href="http://zepid.readthedocs.io/en/latest/Inverse%20Probability%20Weights.html#time-varying">zEpid Docs &ndash; MSM with IPW-KM<br />&#8203;</a><br />For further description of the above features and others, a guide is available at <a href="http://zepid.readthedocs.io/en/latest/">http://zepid.readthedocs.io/en/latest/</a><br /><br /><br /><em>Note: </em>At the time of this blog post, we are on version 0.1.3<br />&#8203;</div>  <h2 class="wsite-content-title"><strong><font size="4">Download zEpid</font></strong></h2>  <div class="paragraph">You can download zEpid via GitHub, PyPI, or directly from the command line using</div>  <blockquote>pip install zepid</blockquote>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <div><div class="wsite-multicol"><div class="wsite-multicol-table-wrap" style="margin:0 -15px;"> 	<table class="wsite-multicol-table"> 		<tbody class="wsite-multicol-tbody"> 			<tr class="wsite-multicol-tr"> 				<td class="wsite-multicol-col" style="width:50%; padding:0 15px;"> 					 						  <div class="paragraph"><span>In the background, zEpid uses:</span><ul><li>NumPy</li><li>SciPy</li><li>pandas&nbsp;</li><li>statsmodels&nbsp;</li><li>matplotlib</li><li>tabulate</li></ul></div>   					 				</td>				<td class="wsite-multicol-col" style="width:50%; padding:0 15px;"> 					 						  <div class="paragraph" style="text-align:left;">&#8203;If you are interested in conducting analyses in Python, I also recommend the packages:<ul><li>lifelines (survival analysis tools)&nbsp;</li><li>biopython (biological computation tools and search PubMed)&nbsp;</li><li>seaborn (improved visualizations)</li><li>sas7bdat (read in SAS files)</li><li>sklearn (machine learning models)</li><li>NetworkX (network analysis)</li></ul></div>   					 				</td>			</tr> 		</tbody> 	</table> </div></div></div>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/download_orig.png" alt="zEpid - a Python library for epidemiology tools" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><span>For an introduction to Python intended for epidemiologists, I have a guide in development at&nbsp;</span><a href="https://github.com/pzivich/Python-for-Epidemiologists">https://github.com/pzivich/Python-for-Epidemiologists</a><span>&nbsp;</span><br /><br /><span>&#8203;Note that zEpid is distributed under the MIT license.&nbsp;</span>&#8203;<br /><br /><br />&#8203;Paul</div>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <div class="paragraph"><strong>About the Author</strong></div>  <div><div class="wsite-multicol"><div class="wsite-multicol-table-wrap" style="margin:0 -15px;"> 	<table class="wsite-multicol-table"> 		<tbody class="wsite-multicol-tbody"> 			<tr class="wsite-multicol-tr"> 				<td class="wsite-multicol-col" style="width:35.639686684073%; padding:0 15px;"> 					 						  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/editor/paulzivich-zepid.jpg?1531012185" alt="Paul Zivich - creator of zEpid - a Python library for epidemiology tools" style="width:244;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>   					 				</td>				<td class="wsite-multicol-col" style="width:64.360313315927%; padding:0 15px;"> 					 						  <div class="paragraph"><font size="2">&nbsp;<br />Paul Zivich is an epidemiology PhD student at University of North Carolina at Chapel Hill. His interests include infectious disease epidemiology and causal inference in the presence of interference.<br />&#8203;<br />To request features or ask questions, contact him on <a href="https://github.com/pzivich/zepid">GitHub</a> at /pzivich/zepid, on Twitter <a href="https://twitter.com/zepidpy">@zEpidpy</a>, or by <a href="mailto:zepidpy@gmail.com">email</a>.</font></div>   					 				</td>			</tr> 		</tbody> 	</table> </div></div></div>]]></content:encoded></item><item><title><![CDATA[Calculate Mean or Average Value in SAS]]></title><link><![CDATA[http://www.baileydebarmore.com/epicode/calculate-mean-or-average-value-in-sas]]></link><comments><![CDATA[http://www.baileydebarmore.com/epicode/calculate-mean-or-average-value-in-sas#comments]]></comments><pubDate>Thu, 14 Jun 2018 14:23:42 GMT</pubDate><category><![CDATA[Bailey DeBarmore]]></category><category><![CDATA[SAS]]></category><guid isPermaLink="false">http://www.baileydebarmore.com/epicode/calculate-mean-or-average-value-in-sas</guid><description><![CDATA[Author: Bailey DeBarmore  &#8203;Short post today on how to use the MEAN function in SAS 9.4. Let's get started.It seems like every time I need to calculate a mean variable in SAS, I find myself looking up which CALL functions deal with missing values in this way, and which in that way.&nbsp;For example, blood pressure readings are often taken 3 times, and then we average those 3 readings together for a mean value. In some code I ran earlier this morning, I kept getting negative values in my "av [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><em><font size="2">Author: Bailey DeBarmore</font></em></div>  <div class="paragraph">&#8203;<span>Short post today on how to use the MEAN function in SAS 9.4. Let's get started.</span><br /><br /><span><span>It seems like every time I need to calculate a mean variable in SAS, I find myself looking up which CALL functions deal with missing values in this way, and which in that way.&nbsp;</span><br /><br /><span>For example, blood pressure readings are often taken 3 times, and then we average those 3 readings together for a mean value. In some code I ran earlier this morning, I kept getting negative values in my "avg_bp" variable. What's up with that?&nbsp;</span><br /></span></div>  <div>  <!--BLOG_SUMMARY_END--></div>  <div class="paragraph">The code I had used was:</div>  <blockquote>avg_bp=mean(bp1-bp3)</blockquote>  <div class="paragraph">Looks OK right?<br />&#8203;<br />Then I tried:</div>  <blockquote>avg_bp=average(bp1-bp3)</blockquote>  <div class="paragraph"><br />&#8203;Guess what? There's no average function in SAS. Oops!<br />&#8203;<br />&#8203;Then I tried:</div>  <blockquote>avg_bp=mean(of bp1-bp3)</blockquote>  <div class="paragraph"><br />&#8203;and ta da! Perfecto!</div>  <h2 class="wsite-content-title"><strong><font size="4">Syntax for MEAN function</font></strong></h2>  <div class="paragraph"><span>The syntax of the MEAN statement varies depending on how you list your variables.&nbsp;</span><br /><span><span>1) If you use a dash list, like I did, you need to include "of"</span><br /><span>2) If you separate variables with a comma, you do not need to include 'of'.&nbsp;</span></span></div>  <h2 class="wsite-content-title"><strong><font size="4">SUM versus MEAN</font></strong></h2>  <div class="paragraph">So why wouldn't you just use</div>  <blockquote>avg_bp=SUM(of bp1-bp3)/3</blockquote>  <div class="paragraph"><span>Well, with SUM, if there is a missing value, SUM treats it as a zero. Usually if we only have 2 out of 3 values, when we calculate the average, we would do bp1+bp2 divided by 2, right? If you use SUM and a fixed divisor, you need to be sure that you have NO MISSINGNESS. In contrast, the MEAN function will manage missing values appropriately. That is, if you're missing 2 of 3 values, it will divide by 2 (not 3).&nbsp;</span><br /><br /><span><em><span>NB: Don't just exclude all your missing values! That's a post for another day, but briefly, if you exclude observations with missing values you can introduce bias. Persons with all missing values versus 1 versus 2 out of the 3 may be different in some systematic way. You're also reducing your precision by excluding those.&nbsp;</span></em><br /><br /></span></div>  <h2 class="wsite-content-title"><strong><font size="4">Take Home Message</font></strong></h2>  <div class="paragraph"><span>In summary,&nbsp; to calculate the mean value, be sure to use the MEAN function so that it will manage missing values appropriately, and be sure to use the correct syntax to avoid wonky results (use "of" with a - list, otherwise use a comma separated list, see below).&nbsp;</span>&#8203;</div>  <blockquote>NEWVAR = mean(of VAR1-VAR3)<br />&#8203;NEWVAR = mean(VAR1, VAR2, VAR3)<br /></blockquote>  <div class="paragraph"><br /><span>That's all for today - quick and dirty, but useful. Now every time I look this up, I'll just come back to my own blog post! Just kidding - hopefully writing this post for you guys has solidified the concept.&nbsp;</span>&#8203;&#8203;<br /><br /><br />&#8203;Bailey<br /><br />&#8203;<br /></div>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <div class="paragraph"><strong>About the Author</strong></div>  <div><div class="wsite-multicol"><div class="wsite-multicol-table-wrap" style="margin:0 -15px;"> 	<table class="wsite-multicol-table"> 		<tbody class="wsite-multicol-tbody"> 			<tr class="wsite-multicol-tr"> 				<td class="wsite-multicol-col" style="width:29.673202614379%; padding:0 15px;"> 					 						  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/published/ga0a1948e.jpg?1531011594" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>   					 				</td>				<td class="wsite-multicol-col" style="width:70.326797385621%; padding:0 15px;"> 					 						  <div class="paragraph"><br /><font size="2">&#8203;Bailey DeBarmore is a doctoral student at the University of North Carolina at Chapel Hill studying epidemiology. Find her on Twitter <a href="https://twitter.com/BaileyDeBarmore" target="_blank">@BaileyDeBarmore</a> and blogging for the American Heart Association on the <a href="https://earlycareervoice.professional.heart.org/author/guestblogger3heart-org/" target="_blank">Early Career Voice </a>blog.&nbsp;</font></div>   					 				</td>			</tr> 		</tbody> 	</table> </div></div></div>]]></content:encoded></item><item><title><![CDATA[P for trend]]></title><link><![CDATA[http://www.baileydebarmore.com/epicode/p-for-trend]]></link><comments><![CDATA[http://www.baileydebarmore.com/epicode/p-for-trend#comments]]></comments><pubDate>Tue, 22 May 2018 17:54:21 GMT</pubDate><category><![CDATA[P values]]></category><category><![CDATA[SAS]]></category><category><![CDATA[Stata]]></category><guid isPermaLink="false">http://www.baileydebarmore.com/epicode/p-for-trend</guid><description><![CDATA[Author: Bailey DeBarmoreWhile I'm not a big fan of p values, sometimes your coauthors, reviewers, or editors ask for them. In this post I'll show you how to calculate p for trend for ordered categories, like in a Table 1, and for adjusted odds ratios or similar regression.R users: I don't use R much, but encourage you to search for "prop.trend.test" to learn more about trend tests in R.Jump to:&nbsp;Stata&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SASStataTest for Trend using nptrendI [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><em><font size="2">Author: Bailey DeBarmore</font></em></div><div class="paragraph">While I'm not a big fan of p values, sometimes your coauthors, reviewers, or editors ask for them. In this post I'll show you how to calculate p for trend for ordered categories, like in a Table 1, and for adjusted odds ratios or similar regression.</div><div class="paragraph">R users: I don't use R much, but encourage you to search for "prop.trend.test" to learn more about trend tests in R.<br><br>Jump to:&nbsp;<br><a href="http://www.baileydebarmore.com/epicode/p-for-trend.html#Stata">Stata</a>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br><a href="http://www.baileydebarmore.com/epicode/p-for-trend.html#SAS">SAS</a></div><div><!--BLOG_SUMMARY_END--></div><div><div id="340389633781251985" align="left" style="width: 100%; overflow-y: hidden;" class="wcustomhtml"><div class="anchor"><h2><a name="Stata" id="Stata"></a></h2></div></div></div><h2 class="wsite-content-title">Stata</h2><h2 class="wsite-content-title"><strong><font size="4">Test for Trend using nptrend</font></strong></h2><div class="paragraph"><span>If you want to compare mean values across ordered categories, call the nptrend test after tab (for categorical) or tabstat (for continuous). It is an extension of the Wilcoxon Rank Sum test.&nbsp;</span>&#8203;</div><h2 class="wsite-content-title"><u><span><font size="4">Binary and Ordinal Example</font></span></u></h2><blockquote><span>tab diabetes agegrp, col</span><br><span><span>nptrend diabetes, by(agegrp)</span></span></blockquote><div class="paragraph"><span>You can stratify, too.&nbsp;</span><br><span><br></span></div><blockquote><span>sort male</span><br><span><span>by male: tab diabetes agegrp, col</span><br><span>nptrend diabetes if male==0, by(agegrp)</span><br><span>nptrend diabetes if male==1, by (agegrp)</span></span></blockquote><div class="paragraph" style="text-align:left;"><span>This code produces proportions of diabetes by age group and then tests for trend by age group. The second block of code does this tabulation and trend test separately for males and females.&nbsp;<br><br>&#8203;Note the difference in tab versus nptrend in the by group syntax: in tab, agegrp is included before the comma with no additional words, but in nptrend (and later in tabstat) you include it after the comma with a by().&nbsp;</span></div><h2 class="wsite-content-title"><u><font size="4">Continuous and Ordinal Example</font></u></h2><blockquote><span>tabstat bmi, by(agegrp) stats(mean sd) format(%9.2f)</span><br><span><span>nptrend bmi, by(agegrp)&nbsp;</span></span>&#8203;</blockquote><div class="paragraph"><span>This code produces mean and sd of BMI by age group to 2 decimal places and then produces a test for trend by age group. Note that the syntax of the by grouping is similar in both tabstat and agegrp.</span></div><div class="paragraph"><span>The default when you omit the stats option is to only give you the mean.<br><br>Other statistics you can request are mean, count, n, sum, max, min, range, sd, variance, cv, semean, skewness, kurtosis, p1, p5, p10, p25, median, p50, p75, p90, p95, p99, iqr, q.<br><br>Note that p50 is the same as median, and q is the same as writing p25 p50 and p75.<br><br>Count is the count of nonmissing observations and is the same as n.<br><br>&#8203;CV is the coefficient of variation (sd/mean) and semean is the se of the mean (sd/sq rt n).&nbsp;</span>&#8203;</div><div class="paragraph"><span>You can stratify here, too.&nbsp;</span>&#8203;</div><blockquote><span>sort male</span><br><span><span>by male: tabstat bmi, by(agegrp) stats(mean sd) format(%9.2f)</span><br><span>nptrend bmi if male==0, by(agegrp)</span><br><span>nptrend bmi if male==1, by(agegrp)</span></span></blockquote><div><div style="height: 20px; overflow: hidden; width: 100%;"></div><hr class="styled-hr" style="width:100%;"><div style="height: 20px; overflow: hidden; width: 100%;"></div></div><div class="paragraph"><strong>ADJUSTED ESTIMATES: Test for Trend using Post-Estimation</strong></div><div class="paragraph">&#8203;After you conduct a regression with a categorical variable, you can test for trend using the post-estimation&nbsp;<a href="https://www.stata.com/manuals13/rcontrast.pdf" target="_blank">CONTRAST</a>&nbsp;command.<br><br>You will want to indicate your categorical variable using the i. prefix in your regression statement. Then, when you call on CONTRAST (immediately after the regression) you can use a prefix for that variable that indicates the type of trend you want to look at.&nbsp;<br><br>Let's look at BMI (continuous) and age group in a linear regression (or ANOVA in this case).&nbsp;&nbsp;</div><blockquote><span>anova bmi agegrp race</span></blockquote><div class="paragraph">or</div><blockquote><span>regress bmi i.agegrp race</span></blockquote><div class="paragraph"><span>You can run these contrast statements (and others)&nbsp;</span>&#8203;</div><div class="paragraph"><span>1. Difference from reference level&nbsp;</span>&#8203;</div><blockquote><span>contrast r.agegrp</span></blockquote><div class="paragraph"><span>2. Difference from next level</span></div><blockquote><span>contrast a.agegrp</span><br><br></blockquote><div class="paragraph"><span>3. Difference from previous level&nbsp;</span>&#8203;</div><blockquote><span>contrast ar.agegrp</span></blockquote><div class="paragraph">4.&nbsp;<span>Looking p-for-trend for linear, quadratic, cubic, quartic, and joint&nbsp;</span><span><br></span></div><blockquote><span>contrast p.agegrp, noeffects&nbsp;</span>&#8203;</blockquote><div class="paragraph"><em><span>Using the p. prefix is only meaningful if you have ordinal categories.&nbsp;</span></em><span><br></span></div><div class="paragraph"><br><br><span>If you're using a non-linear model, you can use the same contrast post-estimation statements after your regression, such as:&nbsp;</span>&#8203;<br></div><blockquote><span>logit diabetes i.agegrp race bmi</span><br><span><span>contrast p.agegrp, noeffects&nbsp;</span></span>&#8203;</blockquote><div class="paragraph">or</div><blockquote><span>logistic diabetes i.agegrp race bmi</span><br><span><span>contrast p.agegrp, noeffects&nbsp;</span></span>&#8203;</blockquote><div><div style="height: 20px; overflow: hidden; width: 100%;"></div><hr class="styled-hr" style="width:100%;"><div style="height: 20px; overflow: hidden; width: 100%;"></div></div><h2 class="wsite-content-title">SAS</h2><h2 class="wsite-content-title"><strong><font size="3">Test for Trend using PROC FREQ: Binary and Ordinal</font></strong></h2><div class="paragraph"><span>If you have a binary variable and a ordinal variable, you can use PROC FREQ to generate your trend test using the Cochran-Armitage test in the TABLES statement. It will test for trend across the column variable.&nbsp;</span><br><br><span><em><span>Just a refresher for which is the row and which is the column variable.&nbsp;</span></em></span><br></div><blockquote><span>PROC FREQ data=[data];</span><br><span><span>TABLES row * col / trend;</span><br><span>run;</span></span></blockquote><div class="paragraph"><span>You may also want to request confidence limits (CL) and measures (MEASURES) with your trend test.&nbsp;</span><br><br><span><span>You can get the same results as the Stata nptrend by specifying SCORES=MIDRIDIT in the TABLES statement, after the / .</span></span></div><blockquote><span>PROC FREQ data=stroke;</span><br><span><span>TABLES diabetes * agegrp / trend;</span><br><span>run;</span></span></blockquote><div class="paragraph">&#8203;This code will give you a test for trend of diabetes frequency across age groups. The output you're looking for is titled "Cochran-Armitage Trend Test". The one-sided p-value is for a test of trend in a pre-defined direction. The two-sided p-value is for a test of trend when you don't know what direction to expect. (I'm partial to two-sided p-values).&nbsp;<br><br>A small p-value means you can reject the null hypothesis of NO TREND.<br></div><h2 class="wsite-content-title"><strong><font size="3">Test for Trend using PROC NPAR1WAY: Continuous and Ordinal</font></strong></h2><div class="paragraph">If you want to test for trend with a continuous variable across ordinal categories, you can use PROC NPAR1WAY and request the Wilcoxon Rank Sum test.&nbsp;</div><blockquote>&#8203;<span>PROC NPAR1WAY data=stroke WILCOXON;</span><br><span><span>CLASS agegrp;</span><br><span>VAR bmi;</span><br><span>*exact wilcoxon;</span><br><span>&#8203;run;</span></span></blockquote><div class="paragraph">This code would compute p for trend of BMI as a continuous variable across age groups. Note that if you have a small sample size that likely does not meet the normal distribution assumptions, you should include the "exact wilcoxon" statement.<br><br>In the output, look for the Normal Approximation two-sided p-value, where a small p-value let's you reject the null hypothesis of no trend. If you used the exact option, look for the two-sided p-value under Exact Test.&nbsp;<br></div><div><div style="height: 20px; overflow: hidden; width: 100%;"></div><hr class="styled-hr" style="width:100%;"><div style="height: 20px; overflow: hidden; width: 100%;"></div></div><div class="paragraph"><strong>ADJUSTED ESTIMATES: Test for Trend</strong></div><div class="paragraph">In the output from PROC LOGISTIC, the "Testing Global Null Hypothesis: BETA=0" is equivalent to the Cochran-Armitage test used in PROC FREQ, but for your adjusted odds ratios.&nbsp;<br><br>You can also ask for separate Wald tests of the betas by using the TEST statement.</div><blockquote>&#8203;PROC LOGISTIC data=[data];<br>MODEL diabetes = agegrp bmi race;<br>TEST agegrp;<br>run;</blockquote><div class="paragraph" style="text-align:left;">Hopefully you found this post helpful in understanding exactly what your output is giving you. I know I learned a lot just by researching it for you.&nbsp;<br><br>&#8203;Bailey</div><div><div style="height: 20px; overflow: hidden; width: 100%;"></div><hr class="styled-hr" style="width:100%;"><div style="height: 20px; overflow: hidden; width: 100%;"></div></div><div class="paragraph"><strong>About the Author</strong></div><div><div class="wsite-multicol"><div class="wsite-multicol-table-wrap" style="margin:0 -15px;"><table class="wsite-multicol-table"><tbody class="wsite-multicol-tbody"><tr class="wsite-multicol-tr"><td class="wsite-multicol-col" style="width:24.151436031332%; padding:0 15px;"><div><div class="wsite-image wsite-image-border-none" style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"><a><img src="http://www.baileydebarmore.com/uploads/2/4/8/5/24852402/ga0a1948e_1_orig.jpg" alt="Picture" style="width:auto;max-width:100%"></a><div style="display:block;font-size:90%"></div></div></div></td><td class="wsite-multicol-col" style="width:75.848563968668%; padding:0 15px;"><div class="paragraph"><font size="2"><br>&#8203;Bailey DeBarmore is a doctoral student at the University of North Carolina at Chapel Hill studying epidemiology. Find her on Twitter&nbsp;<a href="https://twitter.com/BaileyDeBarmore" target="_blank">@BaileyDeBarmore</a>&nbsp;and blogging for the American Heart Association on the&nbsp;<a href="https://earlycareervoice.professional.heart.org/author/guestblogger3heart-org/" target="_blank">Early Career Voice&nbsp;</a>blog.&nbsp;</font></div></td></tr></tbody></table></div></div></div>]]></content:encoded></item></channel></rss>