Convert a character vector of mixed numbers, fractions, and integers to numeric

fractions, r

Solution

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

Problem

I'm trying to write an R function to convert fractions and mixed numbers to decimals. e.g. ``` 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 ``` This works for most of the cases I can think of, but feels a little bit hackish. Is there a more standard way to do this?

Original source