How can we split an integer number into a vector of its constituent digits in R
15,043
Solution 1
Convert to character then split will do the trick
a <- 6547
as.numeric(strsplit(as.character(a), "")[[1]])
## [1] 6 5 4 7
Solution 2
(a %% c(1e4, 1e3, 1e2, 1e1)) %/% c(1e3, 1e2, 1e1, 1e0)
This is 3-4x as fast on my computer than doing a strsplit. But the strsplit is a lot more elegant and the difference decreases with longer vectors.
library(microbenchmark)
microbenchmark((a %% c(1e4, 1e3, 1e2, 1e1)) %/% c(1e3, 1e2, 1e1, 1e0))
# median of 1.56 seconds
microbenchmark(as.numeric(strsplit(as.character(a), "")[[1]]))
# median of 8.88 seconds
Edit: using Carl's insight, here is a more general version.
a <- 6547
dig <- ceiling(log10(a))
vec1 <- 10^(dig:1)
vec2 <- vec1/10
(a%%vec1)%/%vec2
Solution 3
This also works. It's slower than the other answers, but possibly easier to read...
library(stringr)
as.integer(unlist(str_split(a, "")))[-1]
Related videos on Youtube
Author by
Remi.b
Updated on June 30, 2022Comments
-
Remi.b almost 2 years
I think an example should make things clear enough.
I have
a_1 = 6547
and I want some function that transform a_1 into the following a_2
a_2 = c(6, 5, 4, 7)
-
Carl Witthoft over 10 yearsFound the link: stackoverflow.com/questions/18786432/…
-
-
Carl Witthoft over 10 yearsYou should rewrite to handle the general case, by calculating
log10(a)
and using the (truncated or rounded) value to set the maximum power you wish to divide by. I wrote the code for that in some previous answer on SO but can't track it down just now. -
CHP over 10 yearsInteresting approach. Would be interesting to see if this is faster for very long vectors?
-
Arno Kalkman over 9 yearsThis code is actually incorrect and fails for numbers which are a power of 10, (100,1000,10000 etc.). This can easily be explained by the fact that ceiling(log10(1000)) == 3, and not 4. I think the code can be corrected by: dig <- floor(log10(a)+1). It also does not work for 0, but my change does not fix that.