Jacek Kotowski
Jacek Kotowski

Reputation: 704

mutate_if and mutate_at functionality in one line

Is it possible to (1) use select helpers and (2) check type of columns to apply a function?

For example this will not work - I would like to convert to factor all integer columns the names of which do not contain "VAL":

dane_usa_nr%>% 
  mutate_at(vars(!contains("VAL")) & is.integer , as.factor)

Is it possible with some other syntax in dplyr?

Upvotes: 2

Views: 178

Answers (2)

smingerson
smingerson

Reputation: 1438

Try this. It'll mutate all columns not containing "VAL". It'll then check if it is integer. If it is, it'll use as.factor(). If it isn't, it'll simply return the column.

dane_usa_nr%>% 
  mutate_at(vars(!contains("VAL")), function(x) if (is.integer(x)) as.factor(x) else x)

Upvotes: 3

Ronak Shah
Ronak Shah

Reputation: 388907

Not exactly a dplyr way to do this but you can create a logical vector which satisfies the condition needed.

inds <- (!grepl("VAL", names(dane_usa_nr))) & (sapply(dane_usa_nr, is.integer))

and then use this vector in mutate_if

library(dplyr)
dane_usa_nr %>%  mutate_if(inds, as.factor)

Or lapply

dane_usa_nr[inds] <- lapply(dane_usa_nr[inds], as.factor)

We can also get the indices and use it in mutate_at

inds <- intersect(grep("VAL", names(dane_usa_nr), invert = TRUE), 
                  which(sapply(dane_usa_nr, is.integer)))

dane_usa_nr %>% mutate_at(inds, as.factor)

The base R implementation remains the same in this case.

Upvotes: 1

Related Questions