Reputation: 2185
In order to use the function mutate_if()
from dplyr, I only find a way by defining the functions upstream, like this:
library(dplyr)
data(iris)
f1 <- function(x){ max(x) < 1 }
f2 <- function(x){ x / max(x) }
df <- iris %>%
mutate_if(f1, f2)
Is there a way, like with the arguments vars()
and funs()
in mutate_at()
, to define the function within the mutate_if()
, and not necessary before ?
Upvotes: 0
Views: 224
Reputation: 12155
Sure, you can use anonymous functions in the mutate_if
call:
head(iris)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
# mimic use of is_numeric, then add +2 to each column
iris %>%
mutate_if(function(x) is.numeric(x),
function(x) x + 2) %>%
head
# Or using the newer syntax (thanks to @akrun):
iris %>%
mutate_if(~ is.numeric(.),
~ . + 2) %>%
head
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 7.1 5.5 3.4 2.2 setosa
2 6.9 5.0 3.4 2.2 setosa
3 6.7 5.2 3.3 2.2 setosa
4 6.6 5.1 3.5 2.2 setosa
5 7.0 5.6 3.4 2.2 setosa
6 7.4 5.9 3.7 2.4 setosa
In your case, you max
gives an error if it's given non-numeric data, so we need to check that it's numeric before going into your real test, but it works just fine this way:
iris %>%
mutate_if(function(x) if (is.numeric(x)) max(x) > 1 else FALSE,
function(x) x / max(x)) %>%
head
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 0.6455696 0.7954545 0.2028986 0.08 setosa
2 0.6202532 0.6818182 0.2028986 0.08 setosa
3 0.5949367 0.7272727 0.1884058 0.08 setosa
4 0.5822785 0.7045455 0.2173913 0.08 setosa
5 0.6329114 0.8181818 0.2028986 0.08 setosa
6 0.6835443 0.8863636 0.2463768 0.16 setosa
Upvotes: 3
Reputation: 5893
Just want to note that you can also use the purrr
notation:
iris %>%
mutate_if(~ if (is.numeric(.x)) max(.x) > 1 else FALSE,
~ .x / max(.x))
Upvotes: 0