Mutate with dynamic column names dplyr
What you are trying to do is called one hot encoding or dummy encoding. Even as this may be possible to accomplish in dplyr (together with tidyr), I would recommend using the function one_hot() from the library mltools. For an explanation, see the following code snippets:

# set up sample data
df &lt;- data.frame(
  id = 1:4,
  media = factor(c("radio", NA, "tv", "tv"), levels=c("radio", "tv", "cinema"))
)


One Hot Encoding with tidyr:

The following code snippet shows how you would accomplish one hot encoding with dplyr and tidyr (copied from this comment):

library(dplyr)
library(tidyr)

tib &lt;- as_tibble(df)
tib %&gt;% 
  mutate(i = 1) %&gt;% 
  spread(media, i, fill = 0)


However, this code will give you the following table:

# A tibble: 4 x 4
 id    radio   tv   `&lt;NA&gt;`
&lt;int&gt;  &lt;dbl&gt;  &lt;dbl&gt;  &lt;dbl&gt;
  1      1      0      0
  2      0      0      1
  3      0      1      0
  4      0      1      0


Note that there is no cinema column present, even though we defined a respective level in our sample data-frame. Also, the spread()-function created an own column for values with NA's, treating them as a separate category.

One Hot Encoding with mltools (recommended):

library(data.table)
library(mltools)

dt &lt;- data.table(df)
one_hot(dt)


This code will give you the following table:

id  color_radio  color_tv  color_cinema
1          1          0            0
2         NA         NA           NA
3          0          1            0
4          0          1            0


As you can see, the column cinema is now present even though our sample data-frame did not contain any observations of it. Also, there isn't an NA-column present anymore. The NA from the second row is instead visible in all columns (which makes way more sense, since you don't know, what category this observation IS, so you cannot know what category it IS NOT).

In addition, this code is not only easier to understand it also runs about two to three times as fast.