13

I was looking for the quite basic numeric function digit sum in R.

  • I did not find a preinstalled function.
  • Even in Stackoverflow's extensive R library I did not find a record.

Therefore tried myself ending with following function:

# Function to calculate a digit sum
digitsum = function (x) {sum(as.numeric(unlist(strsplit(as.character(x), split="")))) }

I works, but I still struggle with following two questions:

  1. Is there really in plain R no function for digit sum?
  2. Is there a smarter way to code this function?
4

4 回答 4

18

这应该更好:

digitsum <- function(x) sum(floor(x / 10^(0:(nchar(x) - 1))) %% 10)
于 2013-09-07T16:35:33.140 回答
8

我想知道三个建议的方法中哪一个(加上第四个)最快,所以我做了一些基准测试。

  1. digitsum1 <- function(x) sum(as.numeric(unlist(strsplit(as.character(x), split = ""))))

  2. digitsum2 <- function(x) sum(floor(x / 10^(0:(nchar(x) - 1))) %% 10)

  3. 使用 GLDEX 包中的函数 digitsBase:

    library(GLDEX, quietly = TRUE)
    digitsum3 <-  function(x) sum(digitsBase(x, base = 10))
    
  4. 基于 Greg Snow 在R-help 邮件列表中的一个功能:

    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 上

于 2016-03-29T00:40:24.197 回答
3

我不确定你为什么会认为会有一个内置函数来做到这一点。它不是真正的统计操作。更多的是数论类型的程序。(通过搜索 Rhelp 档案可以找到许多示例。我为此使用Markmail,但还有其他搜索引擎,如 RSeek、GMane 和纽卡斯尔网页。您的函数将采用一系列数字并返回一个单个数字是所有数字的总和。如果这是目标,那么它看起来设计合理。我猜想人们会想要每个数字的数字总和:

sapply( c(1,2,123), 
        function(x) sum( as.numeric(unlist(strsplit(as.character(x), split=""))) ))
[1] 1 2 6

pkg:GLDEX 中有一个“数字化”功能 digitsBase,您可以用该函数替换您的 as.numeric(unlist(split(as.character(x),""))):

digitsBase(x, 10)
于 2013-09-07T16:29:07.643 回答
0

我为找到 R 中的数字总和所做的工作:

x = readline("Enter the number")
a = as.integer(c(strsplit(x,split="")[[1]]))
print((sum(a)))
于 2019-04-08T18:10:37.873 回答