Character Counting
For small problems, I like the nchar() solution the best, with one modification for negative values:
nDigits <- function(x) nchar( trunc( abs(x) ) )
# Test
nDigits(100)
nDigits(-100)
# both have 3 digits
nDigits(3)
nDigits(-3)
nDigits(0.1)
nDigits(-0.1)
# all have 1 digit
nDigits(1 / .Machine$double.eps)
nDigits(-1 / .Machine$double.eps)
# both have 16 digits
Base 10 Logarithm
If you want to make the logarithm solution work, then you need considerations for negative values and values between 0 and 1. To me, this solution is a tad more complicated:
nDigits2 <- function(x){
  truncX <- floor(abs(x))
  if(truncX != 0){
    floor(log10(truncX)) + 1
  } else {
    1
  }
}
Speed Performance
Here is the output from the microbenchmark comparison (100,000 reps). The code for the character-counting solution is simpler, but slower (by a factor of 3-4):
For integers > 1 (Unit: nanoseconds):
          expr  min   lq      mean median   uq     max neval
  nDigits(100) 1711 2139 2569.2819   2566 2994 2234046 1e+05
 nDigits2(100)    0  428  861.5435    856  856 5670216 1e+05
For really tiny decimals (Unit: nanoseconds):
                           expr  min   lq     mean median   uq     max neval
 nDigits(1/.Machine$double.eps) 2994 4277 5066.321   4705 4705 4477928 1e+05
nDigits2(1/.Machine$double.eps)  428 1283 1588.382   1284 1711 2042458 1e+05