从保存在变量中的字符串计算公式

Calculate formula from string saved in variable

抱歉,我正在努力解决一个非常简单的问题:像 1.28*10^2 这样的 formula/an 表达式被保存为数据框中的一个字符。现在我想将此字符串转换为数值 - 这应该会导致“128”,但它不会。

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)))

变量“eval”最后应包含值 5890、128 和 411000。

任何人都可以帮助我的错误在哪里?谢谢!

默认情况下 eval(parse()) 未矢量化。这里有几个解决方法,

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

1)一次执行一个转换:

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) 或使用 sapply:

mydata %>%
  mutate(eval = sapply(parse(text = formula), eval))

3) 如果所有的公式都是问题中显示的形式那么我们可以将它们转换为e符号并使用as.numeric:

mydata %>%
  mutate(eval = as.numeric(sub('*10^', 'e', formula, fixed = TRUE)))

4) 如果没有 dplyr (2) 和 (3) 可以这样做:

transform(mydata, eval = sapply(parse(text = formula), eval))

transform(mydata, eval = as.numeric(sub('*10^', 'e', formula, fixed = TRUE)))

另一种解决方案,基于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

我认为我们不必使用 rowwise。一个简单的 lapply/purrr::map 就可以完成工作

library(purrr)
library(dplyr)
library(rlang)

mydata %>%
    mutate(result = map_dbl(formula, ~eval(parse_expr(.x))))

我们也可以使用 base R lapply:

mydata$formula[]<-lapply(mydata$formula, \(x) eval(parse(text=x)))

  formula
1    5890
2     128
3  411000