Sorry, but I'm struggling with a quite simple problem: A formula/an expression like 1.28*10^2 is saved as a character in a data frame. Now I want to convert this string into a numeric value - this should result in "128", but it does not.
library(dplyr)
mydata <- data.frame(
formula = c("5.89*10^3", "1.28*10^2", "4.11*10^5")
)
mydata <- mydata %>%
dplyr::mutate(eval = eval(parse(text = formula)))
The variable "eval" should contain the values 5890, 128 and 411000 in the end.
Can anyone help where my mistake is? Thank you!
CodePudding user response:
Yet another solution, based on rlang::parse_expr
:
library(dplyr)
library(rlang)
mydata <- data.frame(
formula = c("5.89*10^3", "1.28*10^2", "4.11*10^5")
)
mydata %>%
rowwise %>%
mutate(eval = eval(parse_expr(formula)))
#> # A tibble: 3 × 2
#> # Rowwise:
#> formula eval
#> <chr> <dbl>
#> 1 5.89*10^3 5890
#> 2 1.28*10^2 128
#> 3 4.11*10^5 411000
CodePudding user response:
By default eval(parse())
is not vectorized. Here are a couple of workarounds,
sapply(mydata$formula, function(i)eval(parse(text = i)))
#5.89*10^3 1.28*10^2 4.11*10^5
# 5890 128 411000
f1 <- function(x)eval(parse(text = x))
f2 <- Vectorize(f1)
mydata %>%
dplyr::mutate(eval = f2(formula))
formula eval
#1 5.89*10^3 5890
#2 1.28*10^2 128
#3 4.11*10^5 411000
CodePudding user response:
I dont think we must use rowwise
. A simple lapply/purrr::map
will do the job
library(purrr)
library(dplyr)
library(rlang)
mydata %>%
mutate(result = map_dbl(formula, ~eval(parse_expr(.x))))
We can also use base R with lapply:
mydata$formula[]<-lapply(mydata$formula, \(x) eval(parse(text=x)))
formula
1 5890
2 128
3 411000
CodePudding user response:
1) Perform one conversion at a time:
library(dplyr)
mydata %>%
rowwise %>%
mutate(eval = eval(parse(text = formula))) %>%
ungroup
## # A tibble: 3 x 2
## formula eval
## <chr> <dbl>
## 1 5.89*10^3 5890
## 2 1.28*10^2 128
3 4.11*10^5 411000
2) or use sapply:
mydata %>%
mutate(eval = sapply(parse(text = formula), eval))
3) If all the formulas are of the form shown in the question then we can convert them to e notation and use as.numeric:
mydata %>%
mutate(eval = as.numeric(sub('*10^', 'e', formula, fixed = TRUE)))
4) Without dplyr (2) and (3) could be done like this:
transform(mydata, eval = sapply(parse(text = formula), eval))
transform(mydata, eval = as.numeric(sub('*10^', 'e', formula, fixed = TRUE)))