г преобразовать десятичные дроби в красивые дроби - PullRequest
1 голос
/ 26 апреля 2019

В 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 - это то, что я хочу получить

1 Ответ

0 голосов
/ 26 апреля 2019

@ 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"
...