分数转小数算法
最近在处理GO富集数据的时候,遇到一个问题:分数形式(113/4193)无法被系统直接识别为数值,在作图时需要横坐标为GeneRatio数据,因此需要一个能将分数转换为浮点型小数的方法。
今天分享一个函数小技巧,主要是正则表达式和多重比较,在R语言和Python中实现对分数和小数的快速转换,使用效果如下:
mixedToFloat(113/4193) [[out]]:0.026949678034
实现原理
mixedToFloat <- function(x){ x <- sapply(x, as.character) is.integer <- grepl("^-?\\d+$", x) is.fraction <- grepl("^-?\\d+\\/\\d+$", x) is.float <- grepl("^-?\\d+\\.\\d+$", x) is.mixed <- grepl("^-?\\d+ \\d+\\/\\d+$", x) stopifnot(all(is.integer | is.fraction | is.float | is.mixed)) numbers <- strsplit(x, "[ /]") ifelse(is.integer, as.numeric(sapply(numbers, `[`, 1)), ifelse(is.float, as.numeric(sapply(numbers, `[`, 1)), ifelse(is.fraction, as.numeric(sapply(numbers, `[`, 1)) / as.numeric(sapply(numbers, `[`, 2)), as.numeric(sapply(numbers, `[`, 1)) + as.numeric(sapply(numbers, `[`, 2)) / as.numeric(sapply(numbers, `[`, 3))))) }
上述代码实现了一个函数 mixedToFloat()
,用于将表示混合数的字符串转换为浮点型数值。函数的输入参数 x
是待转换的字符串,由一个向量或列表组成。函数的输出结果是一个向量,其中包含将输入向量中的字符串转换成浮点型后得到的数值。
解释说明
x <- sapply(x, as.character)
将输入向量中的所有元素强制转换成字符型,赋值给变量x
。is.integer <- grepl("^-?\\d+$", x)
判断当前元素是否为整型,返回一个逻辑向量,其中为TRUE
的元素表示相应元素是整型,否则为FALSE
。is.fraction <- grepl("^-?\\d+\\/\\d+$", x)
判断当前元素是否为分数型,返回一个逻辑向量,其中为TRUE
的元素表示相应元素是分数型,否则为FALSE
。is.float <- grepl("^-?\\d+\\.\\d+$", x)
判断当前元素是否为浮点型,返回一个逻辑向量,其中为TRUE
的元素表示相应元素是浮点型,否则为FALSE
。is.mixed <- grepl("^-?\\d+ \\d+\\/\\d+$", x)
判断当前元素是否为混合型,返回一个逻辑向量,其中为TRUE
的元素表示相应元素是混合型,否则为FALSE
。stopifnot(all(is.integer | is.fraction | is.float | is.mixed)))
确认所有元素均为整型、分数型、浮点型或混合型。numbers <- strsplit(x, "[ /]")
将所有字符串按照空格和正斜杠进行分割(即将混合型拆分成整型和分数型),分割后的结果赋值给变量numbers
。- 如果元素是整型,将其转换成浮点型;如果是浮点型,直接返回其值;如果是分数型或混合型,进行对应的转换和计算。
Python实现方法
可以使用如下的Python代码实现将分数转换为小数的函数:
def convert_fraction_to_decimal(fraction): parts = fraction.split('/') numerator = int(parts[0]) denominator = int(parts[1]) return numerator / denominator
在该函数中,先将分数字符串按照 /
符号拆分成两个部分,分别代表分子和分母。然后将这两个部分都转换为整数类型,最后使用除法算符 /
得到小数值并返回。
例如,如果需要将分数 5/8
转换为小数值,可以调用该函数:
>>> convert_fraction_to_decimal('5/8') 0.625