R: converting fractions into decimals in a data frame

萝らか妹 提交于 2021-02-05 07:14:45

问题


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!


回答1:


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.




回答2:


  1. Firstly, you should prevent your characters from turning into factors in data.frame()

    df <- data.frame(a, b, c, stringsAsFactors = F)

    Then you can wrap a simple sapply/lapply inside your lapply to achieve what you want.

    sapply(X = df, FUN = function(v) {
                                  sapply(X = v,
                                         FUN = function(w) eval(parse(text=w)))
                                 }
      )
    

    Side Notes

  2. If you feed eval an improper expression such as expression(1, 1/2, 2), that evaluates to last value. This explains the 4 4.5 5 output. A proper expression(c(1, 1/2, 2)) evaluates to the expected answer.

  3. The code lapply(df, function(x) eval(parse(text=x))) returns a 3 3 2 because sapply(data.frame(a,b,c), as.numeric) returns:

         a b c
    [1,] 1 2 1
    [2,] 2 1 3
    [3,] 3 3 2
    

    These numbers correspond to the levels() of the factors, through which you were storing your fractions.



来源:https://stackoverflow.com/questions/48955593/r-converting-fractions-into-decimals-in-a-data-frame

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!