As others have noted, this is a programming side-effect more than a statistical irregularity. For my example below, I set the scipen argument in options super high so you can see how many decimals are produced (this argument just shows the scientific notation explicitly so you can see how long the numbers are). An example should make it obvious that even if the mean isn't exactly zero, it is as close as it gets with floating points.
To demonstrate, I have simulated normally distributed data with a mean of 50 and SD of 20 (the values don't really matter but felt like I'd assign something higher than the defaults which won't say much). I also set a random seed to any generic number so it is reproducible.
#### Simulate Data ####
set.seed(123)
options(scipen = 1000000000)
x <- rnorm(n=100,
mean=50,
sd=20)
Then I scale the data and check the mean and standard deviation like you did.
#### Scale and Get Mean/SD ####
scale.x <- scale(x)
mean(scale.x)
sd(scale.x)
When running mean(scale.x), you will see the number is ridiculously long:
0.0000000000000001974408
You may notice there are exactly 23 numbers to the right of the decimal. This is not by accident. Computers that run on 32-bit computers only store 23 digits in binary. This makes sense. R would have to jam a theoretically infinite number of real numbers into a finite number of bits to get to zero. R instead creates a limited expression that is as close to zero as possible.
Running the function sd(scale.x) gives you exactly what you would expect though:
[1] 1
This is because unlike the mean, you are not rounding off a large list of numbers to get the answer. The standard deviation is just the squared root of the variance of $x$, which is usually going to be a non-zero value that will not have many decimals.
An accessible video to this topic can be found at this link.
Edit
While my overall point about the topic still stands, it appears I misspoke about the number of binary digits represented in this estimation. See the below comment by Whuber for more details.
scalemakes the mean zero" means "scalemakes the mean a value that is close to 0, relative to the machine precision of floating point representation." You can learn information about floating point arithmetic in its technical standard, IEEE 754. – Sycorax Jan 26 '23 at 21:05?formatCto specify such things as significant figures, rounding rules, etc. – AdamO Jan 26 '23 at 21:14round(mean(x),10)? – utobi Jan 26 '23 at 21:21Notesection in?Comparison. Also see the references in?Arithmetic