na_if()
substitutes a specified value of a column with
NAs.
%>%
df filter(StockCode == "17011F") %>%
mutate(New_Country = na_if(Country, "Unspecified"), .keep = "used")
Its functioning relies on matchmaking as, when two vectors share the same values at the same positions, those values become NAs.
na_if(c(1, 2, 3, 4, 5),
c(5, 4, 3, 2, 1))
## [1] 1 2 NA 4 5
na_if(c(1, 2, 2, 3),
c(3, 2, 2, 1))
## [1] 1 NA NA 3
The documentation states that the second vector is changed to the type of the first, but I was only able to make it work with the easy conversion between TRUE/FALSE and 1/0.
na_if(0:1, c(FALSE, TRUE))
## [1] NA NA
na_if(c(FALSE, TRUE), 0:1)
## [1] NA NA
na_if(as.character(1:5), 1:5)
## Error in `na_if()`:
## ! Can't convert `y` <integer> to match type of `x` <character>.
The example at the start works because the value “Unspecified” is
recycled to the size of the filtered df
, but we can recycle
only vectors of length 1, so if, in a data frame, we want to substitute
several values the size of the column and the length of the vector used
in na_if()
must match.
%>%
df slice(71:72) %>%
mutate(New_Country = na_if(Country, c("United Kingdom", "France")), .keep = "used")
na_if()
works with columns’ names, not positions.
%>%
df mutate(Country = na_if(8, "Unspecified"))
Error in `mutate()`:
ℹ In argument: `Country = na_if(8, "Unspecified")`.
Caused by error in `na_if()`:
! Can't convert `y` <character> to match type of `x` <double>.
We can use expressions inside it though.
%>%
df mutate(Price_Rank = na_if(min_rank(Price), 1)) %>%
count(Price_Rank) %>%
arrange(!is.na(Price_Rank))
A grouped data frame doesn’t change the functioning of
na_if()
.
%>%
df group_by(Country) %>%
mutate(Country = na_if(Country, "Unspecified"), .keep = "used")