В отношении этого поста , в котором описывается метод в Python, я пытаюсь сделать то же самое в R.
Однако сначала я боролся с выводом MASS::fractions
(см. этот пост ), поскольку мне не было ясно, как обрабатывается точность.
Другой пользователь предложил обходной путь;позже я обнаружил, что numbers::ratFarey
тоже добился цели.
Но потом я решил, что даже если мне удастся получить дроби с желаемым размером знаменателя, я не решу фундаментальную проблему, заключающуюся в том, что числа с плавающей запятой произвольное происхождение не сводится к рациональным числам вообще.
Я подозреваю, что только некоторые, если таковые имеются, исходные числа с плавающей запятой могут быть преобразованы в «правильные» целые числа путем нахождения их соответствующих знаменателей;остальное можно только аппроксимировать, поэтому не стоит даже пытаться найти чрезмерно большие знаменатели.
Я разработал очень простую функцию, которая берет вектор v
чисел с плавающей запятой и выводит коэффициент, который,умноженное на v, выдает как можно больше целых чисел. Максимальный размер знаменателя, используемый при поиске дробей, составляет 1e6.
Я хотел бы услышать ваше мнение об этом / предложения о том, как это можно сделать лучше.
require(numbers)
f_int <- function(v) {
v <- unique(abs(v))
v <- v[!(trunc(v) == v)]
v <- v[v != 0]
if (length(v) == 0) return(1)
f0 <- 10^(-trunc(log10(v)))
r <- sapply(v*f0,function(x) (ratFarey(x,1.e6,upper=F)))
denoms <- r[2,]
nums <- r[1,]
denoms <- f0*denoms
res <- setNames(abs(nums/denoms-v),as.character(denoms))
res <- res[!duplicated(names(res))]
udt <- table(denoms)
res <- res[match(names(udt),names(res))]
udn <- as.numeric(names(udt))
udnfp <- c(1,10*udn[res != 0])
f0_udnfp <- 10^(trunc(log10(udnfp)))
udn <- udn[res == 0]
udt <- udt[res == 0]
if (length(udn) == 0) return(1.e6*max(f0)) else return(mLCM(c(udn,max(f0_udnfp))))
}
РЕДАКТИРОВАТЬ : некоторые примеры данных для v
v <- c((1:10)/300,(1:10)/70,(1:10)/3900)
или
v <- c(0.1234567, 0.142857142857143, 0.0142857142857143, 0.00142857142857143, 0.333333333333333, 0.0333333333333333)
или
v <- c(0.0001234567, 0.142857142857143, 0.0142857142857143, 0.00142857142857143, 0.333333333333333, 0.0333333333333333)