R中的数字和函数

l3zydbqr  于 2023-03-05  发布在  其他
关注(0)|答案(5)|浏览(125)

我在R中寻找非常基本的数值函数digit sum

  • 我没有找到预安装的功能。
  • 即使在Stackoverflow庞大的R库中,我也没有找到任何记录。

因此,尝试自己结束以下函数:

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

我在工作,但我仍在为以下两个问题而挣扎:
1.在普通的R中真的没有数字求和的函数吗?
1.有没有更聪明的方法来编写这个函数?

mwngjboj

mwngjboj1#

这样应该更好:

digitsum <- function(x) sum(floor(x / 10^(0:(nchar(x) - 1))) %% 10)
iswrvxsc

iswrvxsc2#

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

  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)
    1.使用GLDEX包中的函数digitsBase:
library(GLDEX, quietly = TRUE)
digitsum3 <-  function(x) sum(digitsBase(x, base = 10))

1.基于Greg Snow在R-help mailing list中的函数:
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上。

dpiehjr4

dpiehjr43#

我不知道为什么你会认为会有一个内置的函数来做这件事。它不是真正的统计操作。更多的是一种数论程序。(有很多例子可以通过搜索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)
fjnneemd

fjnneemd4#

求R中数字和的方法是:

x = readline("Enter the number")
a = as.integer(c(strsplit(x,split="")[[1]]))
print((sum(a)))
dhxwm5r4

dhxwm5r45#

你可以用x %% 10L得到最后一位数,用x %% 10L去掉最后一位数,这样做,然后在一个循环中用floor(log10(max(x)))重复对最后一位数求和,就给予了结果。

digitsum <- function(x) {
  r <- x %% 10L
  for(i in seq_len(floor(log10(max(x))))) {
    x <- x %/% 10L
    r <- r + x %% 10L
  }
  r
}
digitsum(c(1,2,123))
#[1] 1 2 6

在C++中使用RCPP也是如此。

Rcpp::cppFunction("
Rcpp::IntegerVector sod(const Rcpp::IntegerVector& x) { //sum of digits
  IntegerVector r(no_init(x.size()));
  for(int i=0; i<x.size(); ++i) {
    int s = x[i];
    r[i] = s % 10;
    while(s > 9) {
      s /= 10;
      r[i] += s % 10;
    }
  }
  return r;
}")
sod(c(1,2,123))
#[1] 1 2 6

基准(摘自@Uwe)

x <- 1001L:2000L
digitsum2 <- function(x) sum(floor(x / 10^(0:(nchar(x) - 1))) %% 10)
bench::mark(sapply(x, digitsum2), digitsum(x), sod(x))
#  expression                min   median `itr/sec` mem_alloc gc/se…¹ n_itr  n_gc
#  <bch:expr>           <bch:tm> <bch:tm>     <dbl> <bch:byt>   <dbl> <int> <dbl>
#1 sapply(x, digitsum2)   1.83ms   2.12ms      468.   31.67KB    18.1   207     8
#2 digitsum(x)           18.71µs  19.59µs    50810.   31.62KB    30.5  9994     6
#3 sod(x)                 6.12µs   6.37µs   155482.    6.45KB    15.5  9999     1

相关问题