我正在尝试编写R函数以将分数和带分数转换为小数。例如
mixedToFloat <- function(x){
x <- sub(' ', '+', x, fixed=TRUE)
return(unlist(lapply(x, function(x) eval(parse(text=x)))))
}
> mixedToFloat(c('1 1/2', '2 3/4', '2/3', '11 1/4', '1'))
[1] 1.5000000 2.7500000 0.6666667 11.2500000 1.0000000
这在我能想到的大多数情况下都有效,但感觉有点黑。有没有更标准的方法可以做到这一点?
没有任何“骇人听闻的东西”将不得不解析您的输入并将它们与许多预定义的模式进行匹配。我想出了这个:
mixedToFloat <- function(x){
is.integer <- grepl("^\\d+$", x)
is.fraction <- grepl("^\\d+\\/\\d+$", x)
is.mixed <- grepl("^\\d+ \\d+\\/\\d+$", x)
stopifnot(all(is.integer | is.fraction | is.mixed))
numbers <- strsplit(x, "[ /]")
ifelse(is.integer, 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(c('1 1/2', '2 3/4', '2/3', '11 1/4', '1'))
# [1] 1.5000000 2.7500000 0.6666667 11.2500000 1.0000000
1]使用strapplyc
提取数字,然后calc
将其放入标准格式,将其转换为数字并执行计算:
library(gsubfn)
ff <- c('1 1/2', '2 3/4', '2/3', '11 1/4', '1')
calc <- function(s) {
x <- c(if (length(s) == 2) 0, as.numeric(s), 0:1)
x[1] + x[2] / x[3]
}
sapply(strapplyc(ff, "\\d+"), calc)
[2)另一种方法是将每个表达式转换为有效的R代码,然后解析并评估每个表达式。
sapply(sub(" ", "+", ff), function(x) eval(parse(text = x)))
## 1 1/2 2 3/4 2/3 11 1/4 1
## 1.5000000 2.7500000 0.6666667 11.2500000 1.0000000