问题
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:
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 yourlapply
to achieve what you want.sapply(X = df, FUN = function(v) { sapply(X = v, FUN = function(w) eval(parse(text=w))) } )
Side Notes
If you feed
eval
an improper expression such asexpression(1, 1/2, 2)
, that evaluates to last value. This explains the4 4.5 5
output. A properexpression(c(1, 1/2, 2))
evaluates to the expected answer.The code
lapply(df, function(x) eval(parse(text=x)))
returns a3 3 2
becausesapply(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