{"id":363,"date":"2021-01-27T14:36:49","date_gmt":"2021-01-27T21:36:49","guid":{"rendered":"https:\/\/blogs.ubc.ca\/khead\/?p=363"},"modified":"2021-01-27T18:59:40","modified_gmt":"2021-01-28T01:59:40","slug":"r-versions-of-stata-foreach-loops","status":"publish","type":"post","link":"https:\/\/blogs.ubc.ca\/khead\/r-versions-of-stata-foreach-loops","title":{"rendered":"R versions of Stata foreach loops"},"content":{"rendered":"<p>One thing Stata users miss in R is an easy way to do the following operation.<\/p>\n<p><span style=\"color: #0000ff;\">foreach x of varlist lnw age asq bmi hispanic black other asian schooling cohab married divorced \/\/<\/span><br \/>\n<span style=\"color: #0000ff;\">separated age_cl unsafe llength reg asq_cl appearance_cl provider_second asian_cl black_cl hispanic_cl \/\/ othrace_cl hot massage_cl {<\/span><br \/>\n<span style=\"color: #0000ff;\">egen mean \u2018x\u2019=mean(\u2018x\u2019), by(id)<\/span><br \/>\n<span style=\"color: #0000ff;\">_<\/span><br \/>\n<span style=\"color: #0000ff;\">gen demean \u2018x\u2019=\u2018x\u2019 &#8211; mean \u2018x\u2019 <\/span><\/p>\n<p><span style=\"color: #0000ff;\">drop mean*<\/span><br \/>\n<span style=\"color: #0000ff;\">}<\/span><\/p>\n<p>This example is taken from Scott Cunningham&#8217;s super <img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-364\" src=\"https:\/\/blogs.ubc.ca\/khead\/files\/2021\/01\/stata_vs_R_foreach_demean-225x300.jpeg\" alt=\"\" width=\"225\" height=\"300\" srcset=\"https:\/\/blogs.ubc.ca\/khead\/files\/2021\/01\/stata_vs_R_foreach_demean-225x300.jpeg 225w, https:\/\/blogs.ubc.ca\/khead\/files\/2021\/01\/stata_vs_R_foreach_demean-768x1024.jpeg 768w, https:\/\/blogs.ubc.ca\/khead\/files\/2021\/01\/stata_vs_R_foreach_demean-1152x1536.jpeg 1152w, https:\/\/blogs.ubc.ca\/khead\/files\/2021\/01\/stata_vs_R_foreach_demean-1536x2048.jpeg 1536w, https:\/\/blogs.ubc.ca\/khead\/files\/2021\/01\/stata_vs_R_foreach_demean-scaled.jpeg 1920w\" sizes=\"auto, (max-width: 225px) 100vw, 225px\" \/>book, Causal Inference: the Mixtape. In the lower right of the picture you can see the demeaned variables being created one by one. So how does one perform an operation to create a large number of variables?\u00a0 My preferred method is to take advantage of the .SD functionality in data.table. Create a character vector like this: <span style=\"color: #0000ff;\">myvars &lt;- c(&#8220;lnw&#8221;,&#8221;age&#8221;)<\/span> with all the variables you want.<\/p>\n<p><span style=\"color: #0000ff;\">demean &lt;- function(x) x- mean(x)<\/span><br \/>\n<span style=\"color: #0000ff;\">DM &lt;- DT[,lapply(.SD,demean),by=id,.SDcols=myvars]<\/span><\/p>\n<p>Note how general this is since demean could be replaced a great number of other operations.<\/p>\n<p>Also note that DM won&#8217;t have all the &#8220;demean_lnw&#8221; variables. The demeaned variables in DM keep their names from before. i think that&#8217;s a plus for various reasons.\u00a0 if you want the variable names, Grant McDermott showed me that you just use the := as follows:<\/p>\n<p><span style=\"color: #0000ff;\">DT[, paste0(myvars, &#8216;_demean&#8217;) := lapply(.SD,demean), .SDcols=myvars, by=id]<\/span><\/p>\n<p>However suppose you want to do something more along the lines of a foreach loop. then the following is more like the Stata code in terms of style and effects:<\/p>\n<p><span style=\"color: #0000ff;\">for(i in 1:length(myvars)) {<\/span><br \/>\n<span style=\"color: #0000ff;\">DT &lt;- within(DT,{assign(paste0(&#8220;demean_&#8221;,myvars[i]),get(myvars[i])-ave(get(myvars[i]),id))})<\/span><br \/>\n<span style=\"color: #0000ff;\">}<\/span><\/p>\n<p>The crucial function to learn is <span style=\"color: #0000ff;\">assign<\/span>. Its first argument is string to be used as the name of the variable you&#8217;ll create and the second argument is the value you want to assign to that variabel. The <span style=\"color: #0000ff;\">get<\/span> function just converts a string like &#8220;age&#8221; into an R object <span style=\"color: #0000ff;\">age<\/span>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One thing Stata users miss in R is an easy way to do the following operation. foreach x of varlist lnw age asq bmi hispanic black other asian schooling cohab married divorced \/\/ separated age_cl unsafe llength reg asq_cl appearance_cl provider_second asian_cl black_cl hispanic_cl \/\/ othrace_cl hot massage_cl { egen mean \u2018x\u2019=mean(\u2018x\u2019), by(id) _ gen [&hellip;]<\/p>\n","protected":false},"author":32530,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-363","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.ubc.ca\/khead\/wp-json\/wp\/v2\/posts\/363","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.ubc.ca\/khead\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.ubc.ca\/khead\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.ubc.ca\/khead\/wp-json\/wp\/v2\/users\/32530"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.ubc.ca\/khead\/wp-json\/wp\/v2\/comments?post=363"}],"version-history":[{"count":3,"href":"https:\/\/blogs.ubc.ca\/khead\/wp-json\/wp\/v2\/posts\/363\/revisions"}],"predecessor-version":[{"id":367,"href":"https:\/\/blogs.ubc.ca\/khead\/wp-json\/wp\/v2\/posts\/363\/revisions\/367"}],"wp:attachment":[{"href":"https:\/\/blogs.ubc.ca\/khead\/wp-json\/wp\/v2\/media?parent=363"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.ubc.ca\/khead\/wp-json\/wp\/v2\/categories?post=363"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.ubc.ca\/khead\/wp-json\/wp\/v2\/tags?post=363"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}