{"id":380245,"date":"2023-11-22T14:43:36","date_gmt":"2023-11-22T20:43:36","guid":{"rendered":"http:\/\/matloff.wordpress.com\/?p=2445"},"modified":"2023-11-22T14:43:36","modified_gmt":"2023-11-22T20:43:36","slug":"the-secret-sauce-used-in-many-qeml-functions","status":"publish","type":"post","link":"https:\/\/www.r-bloggers.com\/2023\/11\/the-secret-sauce-used-in-many-qeml-functions\/","title":{"rendered":"The \u201cSecret Sauce\u201d Used in Many qeML Functions"},"content":{"rendered":"<!-- \r\n<div style=\"min-height: 30px;\">\r\n[social4i size=\"small\" align=\"align-left\"]\r\n<\/div>\r\n-->\r\n\r\n<div style=\"border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;\">\r\n[This article was first published on  <strong><a href=\"https:\/\/matloff.wordpress.com\/2023\/11\/22\/the-secret-sauce-used-in-many-qeml-functions\/\"> Mad (Data) Scientist<\/a><\/strong>, and kindly contributed to <a href=\"https:\/\/www.r-bloggers.com\/\" rel=\"nofollow\">R-bloggers<\/a>].  (You can report issue about the content on this page <a href=\"https:\/\/www.r-bloggers.com\/contact-us\/\">here<\/a>)\r\n<hr>Want to share your content on R-bloggers?<a href=\"https:\/\/www.r-bloggers.com\/add-your-blog\/\" rel=\"nofollow\"> click here<\/a> if you have a blog, or <a href=\"http:\/\/r-posts.com\/\" rel=\"nofollow\"> here<\/a> if you don't.\r\n<\/div>\n\n<p>In writing an R package, it is often useful to build up some function call in string form, then \u201cexecute\u201d the string. To give a really simple example:<\/p>\n\n\n\n<pre>&gt; s &lt;- '1+1'\n&gt; eval(parse(text=s))\n[1] 2<\/pre>\n\n\n\n<p>Quite a lot of trouble to go to just to find that 1+1 = 2? Yes, but this trick can be extremely useful, as we\u2019ll see here.<\/p>\n\n\n\n<pre>data(svcensus)\nz &lt;- qePCA(svcensus,'wageinc','qeKNN',pcaProp=0.5)<\/pre>\n\n\n\n<p>This says, \u201cApply Principal Component Analysis to the \u2018svcensus\u2019 data, with enough PCs to get 0.5 of the total variance. Then do k-Nearest Neighbor Analysis, fitting qeKNN to the PCs to predict wage income.\u201d<\/p>\n\n\n\n<p>So we are invoking a qeML function that the user requested, on the user\u2019s requested data. Fine, but the requested qeML function is called using its default values, in this case k = 25, the number of neighbors. What if we want a different value of k, say 50? We can run<\/p>\n\n\n\n<pre>z &lt;- qePCA(svcensus,'wageinc','qeKNN',pcaProp=0.5),\n   opts=list(k=50))<\/pre>\n\n\n\n<p>But how does the internal code of <strong>qePCA<\/strong> handle this? Here is where <strong>eval <\/strong>comes in. Typing <strong>qePCA<\/strong> at the R > prompt shows us the code, two key lines of which are<\/p>\n\n\n\n<pre>cmd &lt;- buildQEcall(qeName,&quot;newData&quot;,yName, \n   opts=opts,holdout=holdout)\nqeOut &lt;- eval(parse(text = cmd))<\/pre>\n\n\n\n<p>So <strong>qeML:::buildQEcall <\/strong>builds up the full call to the user-requested function, including optional arguments, in a character string. Then we use <strong>eval<\/strong> and <strong>parse<\/strong> to execute the string. Inserting a call in <strong>qePCA <\/strong>to <strong>browser<\/strong> (not shown), we can take a look at that string:<\/p>\n\n\n\n<pre>Browse[1]&gt; cmd\n[1] &quot;qeKNN(data = newData,yName=\\&quot;wageinc\\&quot;,holdout = 1000,k=50))&quot;<\/pre>\n\n\n\n<p>So <strong>qeML:::buildQEcall <\/strong>pieced together the call to the user\u2019s requested function, <strong>qeKNN<\/strong>, on the user\u2019s requested data\u2013and with the user\u2019s requested optional arguments. In handling the latter, it among things called <strong>names(opts)<\/strong>, which got the argument names, \u2018k\u2019 here, in string form, exactly what we need.<\/p>\n\n\n\n<p>Note too R\u2019s <strong>call<\/strong> function, which similarly creates a function call. (Yes, <strong>call <\/strong>produces a call, just like <strong>function<\/strong> produces a function.) E.g.,<\/p>\n\n\n\n<pre>&gt; sqrt(2)\n[1] 1.414214\n&gt; sqcall &lt;- call('sqrt',2)\n&gt; class(sqcall)\n[1] &quot;call&quot;\n&gt; eval(sqcall)\n[1] 1.414214<\/pre>\n\n\n\n<p>All of this is an example of R\u2019s <em>metaprogramming<\/em> capabilities\u2013code that produces code\u2013a really cool feature of R that computer science people tend to be ignorant of. Next time you encounter a CS Pythonista who dismisses R as \u201cnot a real language,\u201d reply \u201cR is built on functional programming and OOP models, with powerful metaprogramming facilities\u2026\u201d<\/p>\n\n<div style=\"border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;\">\r\n<div style=\"text-align: center;\">To <strong>leave a comment<\/strong> for the author, please follow the link and comment on their blog: <strong><a href=\"https:\/\/matloff.wordpress.com\/2023\/11\/22\/the-secret-sauce-used-in-many-qeml-functions\/\"> Mad (Data) Scientist<\/a><\/strong>.<\/div>\r\n<hr \/>\r\n<a href=\"https:\/\/www.r-bloggers.com\/\" rel=\"nofollow\">R-bloggers.com<\/a> offers <strong><a href=\"https:\/\/feedburner.google.com\/fb\/a\/mailverify?uri=RBloggers\" rel=\"nofollow\">daily e-mail updates<\/a><\/strong> about <a title=\"The R Project for Statistical Computing\" href=\"https:\/\/www.r-project.org\/\" rel=\"nofollow\">R<\/a> news and tutorials about <a title=\"R tutorials\" href=\"https:\/\/www.r-bloggers.com\/how-to-learn-r-2\/\" rel=\"nofollow\">learning R<\/a> and many other topics. <a title=\"Data science jobs\" href=\"https:\/\/www.r-users.com\/\" rel=\"nofollow\">Click here if you're looking to post or find an R\/data-science job<\/a>.\r\n\r\n<hr>Want to share your content on R-bloggers?<a href=\"https:\/\/www.r-bloggers.com\/add-your-blog\/\" rel=\"nofollow\"> click here<\/a> if you have a blog, or <a href=\"http:\/\/r-posts.com\/\" rel=\"nofollow\"> here<\/a> if you don't.\r\n<\/div>","protected":false},"excerpt":{"rendered":"<p>In writing an R package, it is often useful to build up some function call in string form, then \u201cexecute\u201d the string. To give a really simple example: Quite a lot of trouble to go to just to find that 1+1 = 2? Yes, but this trick can be extremely useful, as we\u2019&#8230;<\/p>\n","protected":false},"author":888,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[4],"tags":[],"aioseo_notices":[],"jetpack-related-posts":[],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/posts\/380245"}],"collection":[{"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/users\/888"}],"replies":[{"embeddable":true,"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/comments?post=380245"}],"version-history":[{"count":1,"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/posts\/380245\/revisions"}],"predecessor-version":[{"id":380246,"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/posts\/380245\/revisions\/380246"}],"wp:attachment":[{"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/media?parent=380245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/categories?post=380245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/tags?post=380245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}