将任何比例四舍五入为最接近的1/r形式的算法

7

在计算比例(0 < x < 1)时,我希望将结果x转换为最接近的1 / r形式,例如

x = 0.30 转换为 1/3

x = 0.29 转换为 1/4

我一直尝试使用MASS中的round()和fractions()来实现,但很少成功。

你认为在R中解决这个问题的最简单的方法是什么?


5
也许我错过了什么,但为什么0.29转换为1/4而不是1/3? - Maurits Evers
2
为什么不直接使用 round(1/x) 或者 ceiling(1/x) 呢?如果您能展示您的尝试并解释它为什么不起作用,那将会很有帮助。 - John Coleman
嗨@MauritsEvers,转换是因为0.29比0.333(1/3)更接近于0.25(1/4)。 - Sergio Henriques
嗨@JohnColeman,除了未能使用rounding x和fractions()之外,我还尝试了列出许多已知值的方法 frac = c(1,0.5,0.3333333,0.25,0.2,0.1666667, 0.1428571, 0.125, 0.1111111, 0.1) 和 min(x - frac) 这种方法有点笨拙,而且只适用于这些值。 - Sergio Henriques
不同,但相关 - https://dev59.com/6W445IYBdhLWcg3wE2Xw - thelatemail
2个回答

2
findR <- function(x){
    possibles <- 1/seq(1:100)
    diffs <- abs(x - possibles)
    1/possibles[which.min(diffs)]}


df <- data.frame(x = seq(.1, .3, .01))
df$r <- sapply(df$x, findR)

      x  r
1  0.10 10
2  0.11  9
3  0.12  8
4  0.13  8
5  0.14  7
6  0.15  7
7  0.16  6
8  0.17  6
9  0.18  6
10 0.19  5
11 0.20  5
12 0.21  5
13 0.22  5
14 0.23  4
15 0.24  4
16 0.25  4
17 0.26  4
18 0.27  4
19 0.28  4
20 0.29  4
21 0.30  3

2
以下代码可能会达到您的目的,返回倒数的上限或下限(哪个结果更好):
f <- function(x) ifelse(abs(1/floor(1/x) - x) < abs(1/ceiling(1/x) - x),floor(1/x),ceiling(1/x))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接