Well, I briefly tried my idea.
I could confirm that the following code snippet works:
str(d)
'data.frame': 5 obs. of 3 variables:
$ a: int 1 2 3 4 5
$ b: chr "a" "a" "a" "a" ...
$ c: Factor w/ 1 level "b": 1 1 1 1 1
d[, sapply(d, class) == 'character']
d[, sapply(d, class) == 'factor']
d[, sapply(d, class) %in% c('character', 'factor')]
Using the correct class, your sapply-approach should work, at least until you enter the missing one ,before the function sapply.
!is.numeric , , numeric, factor, character (, POSIXct, )