Pass function arguments by column position to mutate_at : <p>I'm trying to tighten up a <code>%&gt;%</code> piped workflow where I need to apply the same function to several columns but with one argument changed each time. I feel like <code>purrr</code>'s <code>map</code> or <code>invoke</code> functions should help, but I can't wrap my head around it.</p>

<p>My data frame has columns for life expectancy, poverty rate, and median household income. I can pass all these column names to <code>vars</code> in <code>mutate_at</code>, use <code>round</code> as the function to apply to each, and optionally supply a <code>digits</code> argument. But I can't figure out a way, if one exists, to pass different values for <code>digits</code> associated with each column. I'd like life expectancy rounded to 1 digit, poverty rounded to 2, and income rounded to 0.</p>

<p>I can call <code>mutate</code> on each column, but given that I might have more columns all receiving the same function with only an additional argument changed, I'd like something more concise.</p>



<pre class="lang-r prettyprint-override"><code>library(tidyverse)

df &lt;- tibble::tribble(
        ~name, ~life_expectancy,          ~poverty, ~household_income,
  "New Haven", 78.0580437642378, 0.264221051111753,  42588.7592521085
  )
</code></pre>

<p>In my imagination, I could do something like this:</p>

<pre class="lang-r prettyprint-override"><code>df %&gt;%
  mutate_at(vars(life_expectancy, poverty, household_income), 
            round, digits = c(1, 2, 0))
</code></pre>

<p>But get the error</p>

<blockquote>
  <p>Error in mutate_impl(.data, dots) : 
    Column <code>life_expectancy</code> must be length 1 (the number of rows), not 3</p>
</blockquote>

<p>Using <code>mutate_at</code> instead of <code>mutate</code> just to have the same syntax as in my ideal case:</p>

<pre class="lang-r prettyprint-override"><code>df %&gt;%
  mutate_at(vars(life_expectancy), round, digits = 1) %&gt;%
  mutate_at(vars(poverty), round, digits = 2) %&gt;%
  mutate_at(vars(household_income), round, digits = 0)
#&gt; # A tibble: 1 x 4
#&gt;   name      life_expectancy poverty household_income
#&gt;   &lt;chr&gt;               &lt;dbl&gt;   &lt;dbl&gt;            &lt;dbl&gt;
#&gt; 1 New Haven            78.1    0.26            42589
</code></pre>

<p>Mapping over the digits uses each of the <code>digits</code> options for <em>each</em> column, not by position, giving me 3 rows each rounded to a different number of digits.</p>

<pre class="lang-r prettyprint-override"><code>df %&gt;%
  mutate_at(vars(life_expectancy, poverty, household_income), 
            function(x) map(x, round, digits = c(1, 2, 0))) %&gt;%
  unnest()
#&gt; # A tibble: 3 x 4
#&gt;   name      life_expectancy poverty household_income
#&gt;   &lt;chr&gt;               &lt;dbl&gt;   &lt;dbl&gt;            &lt;dbl&gt;
#&gt; 1 New Haven            78.1    0.3            42589.
#&gt; 2 New Haven            78.1    0.26           42589.
#&gt; 3 New Haven            78      0              42589
</code></pre>

<p><sup>Created on 2018-11-13 by the <a href="https://reprex.tidyverse.org" rel="noreferrer">reprex package</a> (v0.2.1)</sup></p>
