Convert a character vector of mixed numbers, fractions, and integers to numeric
1) This uses strapplyc
to extract the numbers and then calc
puts them in standard form, converts them to numeric and performs the calculation:
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) A different approach is to convert each expression into valid R code and then parse and evaluate each.
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
Anything less "hackish" will have to parse your inputs and match them to a number of pre-defined patterns. I came up with this:
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