1) rrapply We can use rrapply to recursively walk the formula and surround every node that is a syntactic name with Factor(...). Alternately we could use is.word <- function(x) grepl("^\\w+$", x) to check for names that only contain word characters.
library(rrapply)
fo <- a + b * c ~ d + e
is.word <- function(x) make.names(x) == x
insert.Factor <- function(x) substitute(Factor(x), list(x = x))
rrapply(fo, is.word, insert.Factor)
## Factor(a) + Factor(b) * Factor(c) ~ Factor(d) + Factor(e)
If we can have formulas such as
fo2 <- a + b * c ~ I(d) + e
and we want I(Factor(d)) rather than Factor(I)(Factor(d)) then use this for is.word:
is.word <- function(x) make.names(x) == x && format(x) %in% all.vars(fo2)
2) gsub Convert to character string, perform the substitution and convert back. The input, fo, is defined above.
formula(gsub("(\\w+)", "Factor(\\1)", format(fo)), environment(fo))
## Factor(a) + Factor(b) * Factor(c) ~ Factor(d) + Factor(e)
3) Transform data frame If these variables will be obtained from a data frame DF then we could transform its columns and leave the formula as is.
DF[] <- lapply(DF, Factor)