r将小数转换为漂亮的分数

问题描述 投票:1回答:1

Excel有一个函数可以将小数转换为分数('格式单元'>'分数'>'最多一位数(1/4)'等。我想在r中实现这种格式,我找到了两种方法将小数转换为分数,但它们似乎关注准确性而不是人类可读性(相当分数)。

以下是我到目前为止的情况。

decmls <- c(0.155351347,0.04003669,0.005442423,0.000727562,3.37797e-05)

Excel_Fractions <- c("1/6","1/25","4/735","2/2749","3/88811")

MASS::fractions(decmls)
[1]   3398/21873 33042/825293  1053/193480 6629/9111251            0

FRACTION::fra(decmls)
[1] "1553513 / 1e+08" "400367 / 1e+08"  "54424 / 1e+08"   "7276 / 1e+08"    "338 / 1e+08"    

 cbind(decmls
   , Excel_Fractions)
     decmls        Excel_Fractions
[1,] "0.155351347" "1/6"           
[2,] "0.04003669"  "1/25"          
[3,] "0.005442423" "4/735"         
[4,] "0.000727562" "2/2749"        
[5,] "3.37797e-05" "3/88811" 

decmls是玩具数据,Excel_Fractions是我想要的

r excel algorithm numbers fractions
1个回答
0
投票

@camille,感谢您参考分数包

下面是我修改为此问题的函数

library(tidyverse)

decmls <- c(0.155351347,0.04003669,0.005442423,0.000727562,3.37797e-05)

prettyFractions <- function(x = NULL, smbl ="", signif = 3){
 humanity <- function(y){
# y <- t$estPcnt
if (!is.na(y)){
  d <- signif(y, digits = 3) %/% 1e-1

  c <- signif(y, digits = 3) %/% 1e-2
  m <- signif(y, digits = 3) %/% 1e-3
  m1 <- signif(y, digits = 3) %/% 1e-4
  m2 <- signif(y, digits = 3) %/% 1e-5

  if ( y >= 0 ){
    y_is_positive <- ""
  } else {
    y_is_positive <- "-"
  }

  if ( between(d, 1, 10) ) {
    paste0( y_is_positive, smbl
            ,fractional::fractional(y, eps = 1e-02, maxConv = 20, sync = TRUE))
    } else if ( between(c, 1, 10)){
    paste0( y_is_positive, smbl
            ,fractional::fractional(y, eps = 1e-03, maxConv = 20, sync = TRUE))
  } else if ( between(m, 1, 10)){
    paste0( y_is_positive, smbl
            ,fractional::fractional(y, eps = 1e-04, maxConv = 20, sync = TRUE))
   }else if( between(m1, 1, 10)){
    paste0( y_is_positive, smbl
            ,fractional::fractional(y, eps = 1e-06, maxConv = 20, sync = TRUE))
  } else {
    paste0( y_is_positive, smbl
            ,fractional::fractional(y, eps = 1e-09, maxConv = 20, sync = TRUE))
  }
} else if (is.na(y) | is.null(y)){
    "-"
}
}

  sapply(x, humanity)
}

  options("scipen"=100, "digits"=4)

   cbind(decmls
   , Excel_Fractions
   , prettyFracs = prettyFractions(decmls)
   , diff = sapply(Excel_Fractions, function(x) eval(parse(text=x))) 
          - sapply(prettyFractions(decmls), function(x) eval(parse(text=x))))

                  decmls      Excel_Fractions   prettyFracs      diff                         
         1/6     "0.155351347"  "1/6"           "2/13"      "0.0128205128205128"         
        1/25     "0.04003669"   "1/25"          "1/25"      "0"                          
       4/735     "0.005442423"  "4/735"         "1/183"     "-0.0000223040035686409"     
      2/2749     "0.000727562"  "2/2749"        "1/1374"    "-0.000000264751559783845"   
     3/88811     "0.0000337797" "3/88811"       "1/29603"   "-0.000000000760724687222706"
© www.soinside.com 2019 - 2024. All rights reserved.