{"id":861,"date":"2017-07-10T11:07:50","date_gmt":"2017-07-10T09:07:50","guid":{"rendered":"https:\/\/blog.zhaw.ch\/datascience\/?p=861"},"modified":"2018-10-01T11:19:24","modified_gmt":"2018-10-01T09:19:24","slug":"r-reduce-applys-lesser-known-brother","status":"publish","type":"post","link":"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/","title":{"rendered":"R: Reduce() &#8211; apply\u2019s lesser known brother"},"content":{"rendered":"<p>By Thoralf Mildenberger (ZHAW)<\/p>\n<p>Everybody who knows a bit about <code>R<\/code> knows that in general loops are said to be evil and should be avoided, both for efficiency reasons and code readability, although one could argue about both.<\/p>\n<p>The usual advice is to use vector operations and <code>apply()<\/code> and its relatives. <code>sapply()<\/code>, <code>vapply()<\/code> and <code>lapply()<\/code> work by applying a function on each element of a vector or list and return a vector, matrix, array or list of the results. <code>apply()<\/code> applies a function on one of the dimensions of a matrix or array and returns a vector, matrix or array. These are very useful, but they only work if the function to be applied to the data can be applied to each element independently of each other.<\/p>\n<p>There are cases, however, where we would still use a <code>for<\/code> loop because the result of applying our operation to an element of the list depends on the results for the previous elements. The <code>R<\/code> base package provides a function <code>Reduce()<\/code>, which can come in handy here. Of course it is inspired by functional programming, and actually does something similar to the <em>Reduce<\/em> step in <code>MapReduce<\/code>, although it is not inteded for big data applications. Since it seems to be little known even to long-time <code>R<\/code> users, we will look at a few examples in this post.<!--more--><\/p>\n<p>The examples are meant to be illustrative and I do not claim that using <code>Reduce()<\/code> is always the most efficient or clear approach.<\/p>\n<div id=\"the-basic-idea\" class=\"section level2\">\n<h2>The basic idea<\/h2>\n<p><code>Reduce()<\/code> takes a function <code>f<\/code> of two arguments and a list or vector <code>x<\/code> which is to be \u2018reduced\u2019 using <code>f<\/code>. The function is first called on the first two components of <code>x<\/code>, then with the result of that as the first argument and the third component of <code>x<\/code> as the second argument, then again with the result of the second step as first argument and the fourth component of <code>x<\/code> as the second argument etc. The process is continued until all elements of <code>x<\/code> have been processed. With the <code>accumulate<\/code> argument we can tell <code>Reduce()<\/code> to either only return the final result (<code>accumulate == FALSE<\/code>, the default) or all intermediate results (<code>accumulate == TRUE<\/code>). There are a few more arguments that can be used to change the order in which <code>x<\/code> is processed or to provide an initial value, but we won\u2019t use them here.<\/p>\n<p>The help page gives a short description as well as some examples:<\/p>\n<pre class=\"r\"><code>?Reduce<\/code><\/pre>\n<p>As usual with the official help pages, the examples are very condensed and highlight some special features, so we will start with a very easy example here. The <code>cumsum()<\/code> function returns cumulative sums of a vector:<\/p>\n<pre class=\"r\"><code>cumsum(1:6)<\/code><\/pre>\n<pre><code>## [1]  1  3  6 10 15 21<\/code><\/pre>\n<p>This can be thought of as applying the function <span class=\"math display\">f(a,b) = a + b to the vector <\/span><span class=\"math inline\">x = (1, 2, 3, 4, 5, 6)<\/span>:<\/p>\n<p><span class=\"math display\">y_1 = x_1 = 1<br \/>\ny_2 = x_1 + x_2 = f(x_1, x_2) = 1 + 2 = 3<br \/>\ny_3 = y_2 + x_3 = f(y_2, x_3) = 3 + 3 = 6<br \/>\ny_4 = y_3 + x_4 = f(y_3, x_4) = 6 + 4 = 10<br \/>\ny_5 = y_4 + x_5 = f(y_4, x_5) = 10 + 5 = 15<br \/>\ny_6 = y_5 + x_6 = f(y_5, x_6) = 15 + 6 = 21<\/span><\/p>\n<p><span class=\"math display\"><br \/>\n<\/span>or in a more graphical fashion:<\/p>\n<p><a href=\"https:\/\/blog.zhaw.ch\/datascience\/files\/2017\/06\/cumsum2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-867\" src=\"https:\/\/blog.zhaw.ch\/datascience\/files\/2017\/06\/cumsum2-300x300.png\" alt=\"\" width=\"300\" height=\"300\" srcset=\"https:\/\/blog.zhaw.ch\/datascience\/files\/2017\/06\/cumsum2-300x300.png 300w, https:\/\/blog.zhaw.ch\/datascience\/files\/2017\/06\/cumsum2-150x150.png 150w, https:\/\/blog.zhaw.ch\/datascience\/files\/2017\/06\/cumsum2.png 667w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<\/div>\n<p>This means we can use <code>Reduce()<\/code>in the following way to produce the same result as <code>cumsum()<\/code>:<\/p>\n<pre class=\"r\"><code>Reduce(f = \"+\", x = 1:6, accumulate = TRUE)<\/code><\/pre>\n<pre><code>## [1]  1  3  6 10 15 21<\/code><\/pre>\n<p>Note that basic arithmetic operators can be called as functions in <code>R<\/code> when they are quoted:<\/p>\n<pre class=\"r\"><code>\"+\"(1,2)<\/code><\/pre>\n<pre><code>## [1] 3<\/code><\/pre>\n<pre class=\"r\"><code>1 + 2<\/code><\/pre>\n<pre><code>## [1] 3<\/code><\/pre>\n<p>So we do not have to explicitly define our <code>f<\/code> function. We also set <code>accumulate = TRUE<\/code> as <code>accumulate = FALSE<\/code> only returns the final result:<\/p>\n<pre class=\"r\"><code>Reduce(f = \"+\", x = 1:6, accumulate = FALSE)<\/code><\/pre>\n<pre><code>## [1] 21<\/code><\/pre>\n<div id=\"example-joining-multiple-data-frames\" class=\"section level2\">\n<h2>Example: Joining multiple data frames<\/h2>\n<p>A more useful example would be joining multiple data frames with the same ids but different other columns. While there is a ready-made function <code>join_all()<\/code> for this in the <code>plyr<\/code> package, we will see shortly how to solve this task using <code>Reduce()<\/code> using the <code>merge()<\/code> function from base <code>R<\/code>.<\/p>\n<p>Suppose we have a couple of data frames each containing different information about customers of an online shop. They all have a common ID column <code>Customer_ID<\/code>, and we want to join them into one big table.<\/p>\n<pre class=\"r\"><code>df1 &lt;- data.frame(Customer_ID = c(1, 2, 3), Name = c(\"John\", \"Sue\", \"Ann\"))\r\ndf2 &lt;- data.frame(Customer_ID = c(1, 3), Year_First_Order = c(2011, 2017))\r\ndf3 &lt;- data.frame(Customer_ID = c(1, 2, 3), \r\n                  Date_Last_Order = c(\"2017-03-03\", \"2014-03-01\", \"2017-05-30\"),\r\n                  No_Items_Last_Order = c(3, 1, 1),\r\n                  Total_Amount_Last_Order = c(49, 25,25))\r\ndf4 &lt;- data.frame(Customer_ID = c(2, 3), Interested_In_Promo = c(TRUE, FALSE))<\/code><\/pre>\n<p>We could do so by first joining the first two data frames, then join the result with the third, and then join the results of that with the fourth table:<\/p>\n<pre class=\"r\"><code>df_merge &lt;- merge(df1, df2, by = \"Customer_ID\", all.x = TRUE, all.y = FALSE)\r\ndf_merge &lt;- merge(df_merge, df3, by = \"Customer_ID\", all.x = TRUE, all.y = FALSE)\r\ndf_merge &lt;- merge(df_merge, df4, by = \"Customer_ID\", all.x = TRUE, all.y = FALSE)\r\ndf_merge<\/code><\/pre>\n<pre><code>##   Customer_ID Name Year_First_Order Date_Last_Order No_Items_Last_Order\r\n## 1           1 John             2011      2017-03-03                   3\r\n## 2           2  Sue               NA      2014-03-01                   1\r\n## 3           3  Ann             2017      2017-05-30                   1\r\n##   Total_Amount_Last_Order Interested_In_Promo\r\n## 1                      49                  NA\r\n## 2                      25                TRUE\r\n## 3                      25               FALSE<\/code><\/pre>\n<p>We could also store all the data frames in one list and then use <code>merge()<\/code> with the appropriate arguments as our <code>f<\/code> function:<\/p>\n<pre class=\"r\"><code>df_list &lt;- list(df1, df2, df3, df4)\r\nReduce(function(d1, d2) merge(d1, d2, by = \"Customer_ID\", all.x = TRUE, all.y = FALSE), \r\n       df_list)<\/code><\/pre>\n<pre><code>##   Customer_ID Name Year_First_Order Date_Last_Order No_Items_Last_Order\r\n## 1           1 John             2011      2017-03-03                   3\r\n## 2           2  Sue               NA      2014-03-01                   1\r\n## 3           3  Ann             2017      2017-05-30                   1\r\n##   Total_Amount_Last_Order Interested_In_Promo\r\n## 1                      49                  NA\r\n## 2                      25                TRUE\r\n## 3                      25               FALSE<\/code><\/pre>\n<\/div>\n<div id=\"example-sums-of-matrix-powers\" class=\"section level2\">\n<h2>Example: Sums of matrix powers<\/h2>\n<p>We can also combine <code>lapply()<\/code> and <code>Reduce()<\/code>, like in the following example. Given a markov chain with transition matrix <span class=\"math inline\">P<\/span><\/p>\n<pre class=\"r\"><code>P &lt;- rbind(c(0.9, 0.1), c(1, 0))\r\nP<\/code><\/pre>\n<pre><code>##      [,1] [,2]\r\n## [1,]  0.9  0.1\r\n## [2,]  1.0  0.0<\/code><\/pre>\n<p>the matrix <span class=\"math inline\">M(K)<\/span> defined by<\/p>\n<p><span class=\"math display\">M(K) = I + P + P^2 + P^3 + &#8230; + P^K<br \/>\n<\/span><\/p>\n<p>has the following interpretation: Component <span class=\"math inline\">(M(K))_ij<\/span> gives the expected number of time steps the chain stays in state <span class=\"math inline\">j<\/span> when starting in state <span class=\"math inline\">i<\/span>. Give a matrix <span class=\"math inline\">P<\/span> one can of course calculate <span class=\"math inline\">M(K)<\/span> using a loop, but we do it differently. We first create a list of matrix powers (using the matrix power function from the <code>expm<\/code> package):<\/p>\n<pre class=\"r\"><code>library(expm)\r\nP_powers &lt;- lapply(0:20, function(k) P %^% k)\r\nhead(P_powers)<\/code><\/pre>\n<pre><code>## [[1]]\r\n##      [,1] [,2]\r\n## [1,]    1    0\r\n## [2,]    0    1\r\n## \r\n## [[2]]\r\n##      [,1] [,2]\r\n## [1,]  0.9  0.1\r\n## [2,]  1.0  0.0\r\n## \r\n## [[3]]\r\n##      [,1] [,2]\r\n## [1,] 0.91 0.09\r\n## [2,] 0.90 0.10\r\n## \r\n## [[4]]\r\n##       [,1]  [,2]\r\n## [1,] 0.909 0.091\r\n## [2,] 0.910 0.090\r\n<\/code><\/pre>\n<p>We could first think of using <code>sum()<\/code>. <code>sum()<\/code> does not work with lists, and unlisting does not give the desired result, as instead of a matrix the sum of all components of matrix powers is returned:<\/p>\n<pre class=\"r\"><code>sum(unlist(P_powers))<\/code><\/pre>\n<pre><code>## [1] 42<\/code><\/pre>\n<p>But we can use <code>Reduce()<\/code> with <code>\"+\"<\/code>, as this correctly adds the matrices componentwise:<\/p>\n<pre class=\"r\"><code>Reduce(\"+\", P_powers)<\/code><\/pre>\n<pre><code>##          [,1]     [,2]\r\n## [1,] 19.17355 1.826446\r\n## [2,] 18.26446 2.735537<\/code><\/pre>\n<p>One potential drawback compared to using a loop is that we store the whole list of matrix powers, although each power is used only once.<\/p>\n<\/div>\n<div id=\"example-simulating-a-trajectory-of-a-markov-chain-without-a-loop\" class=\"section level2\">\n<h2>Example: Simulating a trajectory of a Markov Chain without a loop<\/h2>\n<p>The next one is a bit hacky but fun: We want to simulate a trajectory from a Markov chain. Suppose we are given the transition matrix, the starting state, and the number of steps to simulate:<\/p>\n<pre class=\"r\"><code>P &lt;- matrix(c(0, 0.1, 0.9, 0.2, 0.5, 0.3, 0, 0.5, 0.5), ncol = 3, byrow = T);\r\nP<\/code><\/pre>\n<pre><code>##      [,1] [,2] [,3]\r\n## [1,]  0.0  0.1  0.9\r\n## [2,]  0.2  0.5  0.3\r\n## [3,]  0.0  0.5  0.5<\/code><\/pre>\n<pre class=\"r\"><code>x_0 &lt;- 2\r\nK &lt;- 100000<\/code><\/pre>\n<p>The idea is the following: We can simulate the next state of the Markov Chain given the current state and a random number from a uniform distribution on <span class=\"math inline\">[0,1]<\/span>:<\/p>\n<pre class=\"r\"><code>newstate &lt;- function(oldstate,u) {\r\n  which.min(u&gt;cumsum(P[oldstate,]))\r\n}\r\n\r\nx_1 &lt;- newstate(x_0, runif(1))\r\nx_1<\/code><\/pre>\n<pre><code>## [1] 1<\/code><\/pre>\n<p>We get the probabilities for the next state from the row of <span class=\"math inline\">P<\/span> that is given by the number of the current state, and we can sample from the states by using comparing a uniform random number to the cumulative sum of the probabilities (this amounts to inverting the cumulative distribution function of the next state give the current one).<\/p>\n<p>Of course, we can use the function <code>newstate()<\/code> on the result and a new random number:<\/p>\n<pre class=\"r\"><code>x_2 &lt;- newstate(x_1, runif(1))\r\nx_2<\/code><\/pre>\n<pre><code>## [1] 3<\/code><\/pre>\n<p>So we could use <code>newstate()<\/code> in <code>Reduce()<\/code>. The only problem is that it takes arguments of different type: The first one is an integer giving the current state, the second one is a real number. Since the integer can be coerced to double, <code>Reduce()<\/code> still works here. We just have to provide a vector that contains the starting state as first component and the <span class=\"math inline\">K<\/span> uniform random numbers needed to generate the following states. We also set <code>accumulate = TRUE<\/code>, because we want the whole trajectory and not only the state at time <span class=\"math inline\">K<\/span>:<\/p>\n<pre class=\"r\"><code>mc_without_loop &lt;- Reduce(newstate, c(x_0, runif(K)), accumulate = TRUE)\r\n\r\nhead(mc_without_loop)<\/code><\/pre>\n<pre><code>## [1] 2 2 3 2 2 2<\/code><\/pre>\n<pre class=\"r\"><code># Distribution of states:\r\n\r\ntable(mc_without_loop)\/length(mc_without_loop)<\/code><\/pre>\n<pre><code>## mc_without_loop\r\n##          1          2          3 \r\n## 0.09183908 0.46318537 0.44497555<\/code><\/pre>\n<\/div>\n<div id=\"further-reading\" class=\"section level2\">\n<h2>Further reading<\/h2>\n<p>The <code>Reduce()<\/code> function is relatively sparsely documented and seems to be widely unknown. It is also often not treated in books on programming in R, even in more advanced ones. Some useful references are<\/p>\n<ul>\n<li>The official help page (<code>?Reduce<\/code>)<\/li>\n<li>Headly Wickham\u2019s book <em>Advanced R<\/em> is available online at <a class=\"uri\" href=\"http:\/\/adv-r.had.co.nz\/\">http:\/\/adv-r.had.co.nz\/<\/a> and <a href=\"http:\/\/adv-r.had.co.nz\/Functionals.html#functionals-fp\">the chapter on functional programming<\/a> contains a short section on <code>Reduce()<\/code>.<\/li>\n<li><a href=\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-part-2-some-pitfalls-using-reduce\/\">Follow-up post on some pitfalls using reduce()<\/a><\/li>\n<\/ul>\n<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<div class=\"pt-sm\">Schlagw\u00f6rter: <a href=\"https:\/\/blog.zhaw.ch\/datascience\/tag\/programming\/\">Programming<\/a>, <a href=\"https:\/\/blog.zhaw.ch\/datascience\/tag\/r\/\">R<\/a><br><\/div>","protected":false},"excerpt":{"rendered":"<p>By Thoralf Mildenberger (ZHAW) Everybody who knows a bit about R knows that in general loops are said to be evil and should be avoided, both for efficiency reasons and code readability, although one could argue about both. The usual advice is to use vector operations and apply() and its relatives. sapply(), vapply() and lapply() [&hellip;]<\/p>\n","protected":false},"author":265,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[1,7,42],"tags":[44,43],"features":[],"class_list":["post-861","post","type-post","status-publish","format-standard","hentry","category-allgemein","category-blog","category-r","tag-programming","tag-r"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>R: Reduce() - apply\u2019s lesser known brother - Data Science made in Switzerland<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"R: Reduce() - apply\u2019s lesser known brother\" \/>\n<meta property=\"og:description\" content=\"By Thoralf Mildenberger (ZHAW) Everybody who knows a bit about R knows that in general loops are said to be evil and should be avoided, both for efficiency reasons and code readability, although one could argue about both. The usual advice is to use vector operations and apply() and its relatives. sapply(), vapply() and lapply() [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/\" \/>\n<meta property=\"og:site_name\" content=\"Data Science made in Switzerland\" \/>\n<meta property=\"article:published_time\" content=\"2017-07-10T09:07:50+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2018-10-01T09:19:24+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.zhaw.ch\/datascience\/files\/2017\/06\/cumsum2-300x300.png\" \/>\n<meta name=\"author\" content=\"mild\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"mild\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/\"},\"author\":{\"name\":\"mild\",\"@id\":\"https:\/\/blog.zhaw.ch\/datascience\/#\/schema\/person\/64f2a57e0efd0aa4c73f45df76618116\"},\"headline\":\"R: Reduce() &#8211; apply\u2019s lesser known brother\",\"datePublished\":\"2017-07-10T09:07:50+00:00\",\"dateModified\":\"2018-10-01T09:19:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/\"},\"wordCount\":1144,\"commentCount\":4,\"image\":{\"@id\":\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/blog.zhaw.ch\/datascience\/files\/2017\/06\/cumsum2-300x300.png\",\"keywords\":[\"Programming\",\"R\"],\"articleSection\":[\"Allgemein\",\"Blog\",\"R\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/\",\"url\":\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/\",\"name\":\"R: Reduce() - apply\u2019s lesser known brother - Data Science made in Switzerland\",\"isPartOf\":{\"@id\":\"https:\/\/blog.zhaw.ch\/datascience\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/blog.zhaw.ch\/datascience\/files\/2017\/06\/cumsum2-300x300.png\",\"datePublished\":\"2017-07-10T09:07:50+00:00\",\"dateModified\":\"2018-10-01T09:19:24+00:00\",\"author\":{\"@id\":\"https:\/\/blog.zhaw.ch\/datascience\/#\/schema\/person\/64f2a57e0efd0aa4c73f45df76618116\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#primaryimage\",\"url\":\"https:\/\/blog.zhaw.ch\/datascience\/files\/2017\/06\/cumsum2.png\",\"contentUrl\":\"https:\/\/blog.zhaw.ch\/datascience\/files\/2017\/06\/cumsum2.png\",\"width\":667,\"height\":667},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\/\/blog.zhaw.ch\/datascience\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"R: Reduce() &#8211; apply\u2019s lesser known brother\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.zhaw.ch\/datascience\/#website\",\"url\":\"https:\/\/blog.zhaw.ch\/datascience\/\",\"name\":\"Data Science made in Switzerland\",\"description\":\"Ein Blog der ZHAW Z\u00fcrcher Hochschule f\u00fcr Angewandte Wissenschaften\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.zhaw.ch\/datascience\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.zhaw.ch\/datascience\/#\/schema\/person\/64f2a57e0efd0aa4c73f45df76618116\",\"name\":\"mild\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/3c38b532abe81ed471e1e6559571ef62f075b055ca6520f8c29ee603a233e272?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/3c38b532abe81ed471e1e6559571ef62f075b055ca6520f8c29ee603a233e272?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/3c38b532abe81ed471e1e6559571ef62f075b055ca6520f8c29ee603a233e272?s=96&d=mm&r=g\",\"caption\":\"mild\"},\"url\":\"https:\/\/blog.zhaw.ch\/datascience\/author\/mild\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"R: Reduce() - apply\u2019s lesser known brother - Data Science made in Switzerland","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/","og_locale":"en_US","og_type":"article","og_title":"R: Reduce() - apply\u2019s lesser known brother","og_description":"By Thoralf Mildenberger (ZHAW) Everybody who knows a bit about R knows that in general loops are said to be evil and should be avoided, both for efficiency reasons and code readability, although one could argue about both. The usual advice is to use vector operations and apply() and its relatives. sapply(), vapply() and lapply() [&hellip;]","og_url":"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/","og_site_name":"Data Science made in Switzerland","article_published_time":"2017-07-10T09:07:50+00:00","article_modified_time":"2018-10-01T09:19:24+00:00","og_image":[{"url":"https:\/\/blog.zhaw.ch\/datascience\/files\/2017\/06\/cumsum2-300x300.png","type":"","width":"","height":""}],"author":"mild","twitter_card":"summary_large_image","twitter_misc":{"Written by":"mild","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#article","isPartOf":{"@id":"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/"},"author":{"name":"mild","@id":"https:\/\/blog.zhaw.ch\/datascience\/#\/schema\/person\/64f2a57e0efd0aa4c73f45df76618116"},"headline":"R: Reduce() &#8211; apply\u2019s lesser known brother","datePublished":"2017-07-10T09:07:50+00:00","dateModified":"2018-10-01T09:19:24+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/"},"wordCount":1144,"commentCount":4,"image":{"@id":"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.zhaw.ch\/datascience\/files\/2017\/06\/cumsum2-300x300.png","keywords":["Programming","R"],"articleSection":["Allgemein","Blog","R"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/","url":"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/","name":"R: Reduce() - apply\u2019s lesser known brother - Data Science made in Switzerland","isPartOf":{"@id":"https:\/\/blog.zhaw.ch\/datascience\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#primaryimage"},"image":{"@id":"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.zhaw.ch\/datascience\/files\/2017\/06\/cumsum2-300x300.png","datePublished":"2017-07-10T09:07:50+00:00","dateModified":"2018-10-01T09:19:24+00:00","author":{"@id":"https:\/\/blog.zhaw.ch\/datascience\/#\/schema\/person\/64f2a57e0efd0aa4c73f45df76618116"},"breadcrumb":{"@id":"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#primaryimage","url":"https:\/\/blog.zhaw.ch\/datascience\/files\/2017\/06\/cumsum2.png","contentUrl":"https:\/\/blog.zhaw.ch\/datascience\/files\/2017\/06\/cumsum2.png","width":667,"height":667},{"@type":"BreadcrumbList","@id":"https:\/\/blog.zhaw.ch\/datascience\/r-reduce-applys-lesser-known-brother\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/blog.zhaw.ch\/datascience\/"},{"@type":"ListItem","position":2,"name":"R: Reduce() &#8211; apply\u2019s lesser known brother"}]},{"@type":"WebSite","@id":"https:\/\/blog.zhaw.ch\/datascience\/#website","url":"https:\/\/blog.zhaw.ch\/datascience\/","name":"Data Science made in Switzerland","description":"Ein Blog der ZHAW Z\u00fcrcher Hochschule f\u00fcr Angewandte Wissenschaften","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.zhaw.ch\/datascience\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.zhaw.ch\/datascience\/#\/schema\/person\/64f2a57e0efd0aa4c73f45df76618116","name":"mild","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/3c38b532abe81ed471e1e6559571ef62f075b055ca6520f8c29ee603a233e272?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/3c38b532abe81ed471e1e6559571ef62f075b055ca6520f8c29ee603a233e272?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3c38b532abe81ed471e1e6559571ef62f075b055ca6520f8c29ee603a233e272?s=96&d=mm&r=g","caption":"mild"},"url":"https:\/\/blog.zhaw.ch\/datascience\/author\/mild\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.zhaw.ch\/datascience\/wp-json\/wp\/v2\/posts\/861","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.zhaw.ch\/datascience\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.zhaw.ch\/datascience\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.zhaw.ch\/datascience\/wp-json\/wp\/v2\/users\/265"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.zhaw.ch\/datascience\/wp-json\/wp\/v2\/comments?post=861"}],"version-history":[{"count":11,"href":"https:\/\/blog.zhaw.ch\/datascience\/wp-json\/wp\/v2\/posts\/861\/revisions"}],"predecessor-version":[{"id":962,"href":"https:\/\/blog.zhaw.ch\/datascience\/wp-json\/wp\/v2\/posts\/861\/revisions\/962"}],"wp:attachment":[{"href":"https:\/\/blog.zhaw.ch\/datascience\/wp-json\/wp\/v2\/media?parent=861"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/datascience\/wp-json\/wp\/v2\/categories?post=861"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/datascience\/wp-json\/wp\/v2\/tags?post=861"},{"taxonomy":"features","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/datascience\/wp-json\/wp\/v2\/features?post=861"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}