Search code examples
rdataframeapplylapplyfractions

R: converting fractions into decimals in a data frame


I am trying to convert a data frame of numbers stored as characters in a fraction form to be stored as numbers in decimal form. (There are also some integers, also stored as char.) I want to keep the current structure of the data frame, i.e. I do not want a list as a result.

Example data frame (note: the real data frame has all elements as character, here it is a factor but I couldn't figure out how to replicate a data frame with characters):

    a <- c("1","1/2","2")
    b <- c("5/2","3","7/2")
    c <- c("4","9/2","5")
    df <- data.frame(a,b,c)

I tried df[] <- apply(df,1, function(x) eval(parse(text=x))). This calculates the numbers correctly, but only for the last column, populating the data frame with that.

Result:

   a  b    c
1  4  4.5  5
2  4  4.5  5
3  4  4.5  5

I also tried df[] <- lapply(df, function(x) eval(parse(text=x))), which had the following result (and I have no idea why):

   a  b  c
1  3  3  2
2  3  3  2
3  3  3  2

Desired result:

   a   b    c
1  1   2.5  4
2  0.5 3    4.5
3  2   3.5  5

Thanks a lot!


Solution

  • You are probably looking for:

    df[] <- apply(df, c(1, 2), function(x) eval(parse(text = x)))
    df
        a   b   c
    1 1.0 2.5 4.0
    2 0.5 3.0 4.5
    3 2.0 3.5 5.0
    
    eval(parse(text = x))
    

    evaluates one expression at a time so, you need to run cell by cell.

    EDIT: if some data frame elements can not be evaluated you can account for that by adding an ifelse statement inside the function:

    df[] <- apply(df, c(1, 2), function(x) if(x %in% skip){NA} else {eval(parse(text = x))}) 
    

    Where skip is a vector of element that should not be evaluated.