提案された 3 つの方法 (および 4 つ目の方法) のうちどれが最も高速なのか疑問に思ったので、ベンチマークを行いました。
digitsum1 <- function(x) sum(as.numeric(unlist(strsplit(as.character(x), split = ""))))
digitsum2 <- function(x) sum(floor(x / 10^(0:(nchar(x) - 1))) %% 10)
パッケージ GLDEX の関数 digitsBase を使用:
library(GLDEX, quietly = TRUE)
digitsum3 <- function(x) sum(digitsBase(x, base = 10))
R-help メーリング リストの Greg Snow による関数に基づいています。
digitsum4 <- function(x) sum(x %/% 10^seq(0, length.out = nchar(x)) %% 10)
ベンチマーク コード:
library(microbenchmark, quietly = TRUE)
# define check function
my_check <- function(values) {
all(sapply(values[-1], function(x) identical(values[[1]], x)))
}
x <- 1001L:2000L
microbenchmark(
sapply(x, digitsum1),
sapply(x, digitsum2),
sapply(x, digitsum3),
sapply(x, digitsum4),
times = 100L, check = my_check
)
ベンチマーク結果:
#> Unit: milliseconds
#> expr min lq mean median uq max neval
#> sapply(x, digitsum1) 3.41 3.59 3.86 3.68 3.89 5.49 100
#> sapply(x, digitsum2) 3.00 3.19 3.41 3.25 3.34 4.83 100
#> sapply(x, digitsum3) 15.07 15.85 16.59 16.22 17.09 24.89 100
#> sapply(x, digitsum4) 9.76 10.29 11.18 10.56 11.48 45.20 100
バリアント 2 はバリアント 1 よりわずかに高速ですが、バリアント 4 と 3 ははるかに低速です。バリアント 4 のコードはバリアント 2 に似ているように見えますが、バリアント 4 の効率は低くなります (ただし、バリアント 3 よりは優れています)。
完全なベンチマーク結果 (グラフを含む) はgithubにあります。