我有以下資料集:
my.df <- data.frame(my_function=rep(c("Var1 Var 2","Var 2-Var1","(Var 2-(Var 2-Var1))/Var 2"), 1),
`Var1`=rep(1:1,3),
`Var 2`=rep(5:5,3), check.names = FALSE)
my.df
# my_function Var1 Var 2
# 1 Var1 Var 2 1 5
# 2 Var 2-Var1 1 5
# 3 (Var 2-(Var 2-Var1))/Var 2 1 5
我想使用名為的列將my_function每一行的值計算到一個名為的新列中outcome
將outcome是:1 5=6, 5-1=4,(5-(5-1))/5=0.2對于每一行。
編輯 正確答案還參考了以下原始資料集:
my.df <- data.frame(my_function=rep(c("1000 2000","2000-1000","(2000-(2000-1000))/2000"), 1), `1000`=rep(1:1,3), `2000`=rep(5:5,3))
uj5u.com熱心網友回復:
回圈遍歷my_function,然后回圈遍歷列名gsub的值,最后進行邪惡的決議:
vars <- colnames(my.df)[ -1 ]
sapply(seq(nrow(my.df)), function(i){
res <- my.df[i, 1]
for(v in vars){
res <- gsub(v, my.df[i, v], res, fixed = TRUE)
}
eval(parse(text = res))
})
# [1] 6.0 4.0 0.2
筆記:
fortunes::fortune("answer is parse")
# If the answer is parse() you should usually rethink the question.
# -- Thomas Lumley
# R-help (February 2005)
uj5u.com熱心網友回復:
一個解決方案可能是:
my.df <- data.frame(my_function=rep(c("1000 2000","2000-1000","(2000-(2000-1000))/2000"), 1), `1000`=rep(1:1,3), `2000`=rep(5:5,3))
my.df
#> my_function X1000 X2000
#> 1 1000 2000 1 5
#> 2 2000-1000 1 5
#> 3 (2000-(2000-1000))/2000 1 5
my.df$my_function = gsub("1000", "X1000", my.df$my_function)
my.df$my_function = gsub("2000", "X2000", my.df$my_function)
my.df$outcome = sapply(split(my.df, 1:NROW(my.df)), function(x)
eval(str2lang(x$my_function),x))
my.df
#> my_function X1000 X2000 outcome
#> 1 X1000 X2000 1 5 6.0
#> 2 X2000-X1000 1 5 4.0
#> 3 (X2000-(X2000-X1000))/X2000 1 5 0.2
但是,您應該閱讀評論,因為評估任意代碼存在安全問題。有關案例,請參見https://stackoverflow.com/a/18391779/6912817。
uj5u.com熱心網友回復:
正如評論中所表達的,我不喜歡從文本中決議代碼,尤其是代碼文本是通過一些用戶輸入生成的。在我看來,這是一種評估這些運算式的安全方法:
library(tidyverse)
my.df <- data.frame(my_function=rep(c("1000 2000","2000-1000","(2000-(2000-1000))/2000"), 1), `1000`=rep(1:1,3), `2000`=rep(5:5,3))
my.df |>
mutate(sub_function = pmap_chr(list(my_function, X1000, X2000),
~gsub(pattern = "1000",
replacement = ..2,
x = ..1) |>
gsub(pattern = "2000",
replacement = ..3)),
eval = map_chr(sub_function, ~as.character(Ryacas::yac_symbol(.x))))
#> my_function X1000 X2000 sub_function eval
#> 1 1000 2000 1 5 1 5 6
#> 2 2000-1000 1 5 5-1 4
#> 3 (2000-(2000-1000))/2000 1 5 (5-(5-1))/5 1/5
uj5u.com熱心網友回復:
使用 rlang 和purrr::pmap_dbl():
library(rlang)
library(purrr)
my.df$outcome <- pmap_dbl(
my.df,
\(my_function, Var1, Var2, ...) {
eval(parse_expr(enexpr(my_function)))
}
)
my.df
my_function Var1 Var2 outcome
1 Var1 Var2 1 5 6.0
2 Var2-Var1 1 5 4.0
3 (Var2-(Var2-Var1))/Var2 1 5 0.2
uj5u.com熱心網友回復:
bquote這是使用and的另一種方法deparse。由于您的示例資料使用整數,我首先將它們轉換numeric為擺脫L輸出中的。
my.df <- data.frame(
my_function = rep(c("Var1 Var 2",
"Var 2-Var1",
"(Var 2-(Var 2-Var1))/Var 2"),
1),
`Var1` = rep(1:1,3),
`Var 2` = rep(5:5,3),
check.names = FALSE)
library(dplyr)
library(stringr)
my.df %>%
mutate(across(starts_with("Var"), as.double)) %>%
rowwise() %>%
mutate(outcome = str_replace_all(my_function,
"(Var\\s{0,1}[0-9] )",
'.(.data[["\\1"]])') %>%
paste0("bquote(", ., ")") %>%
str2lang %>%
eval %>%
list,
outcome = paste0(deparse(outcome), " = ", res = eval(outcome)))
#> # A tibble: 3 x 4
#> # Rowwise:
#> my_function Var1 `Var 2` outcome
#> <chr> <dbl> <dbl> <chr>
#> 1 Var1 Var 2 1 5 1 5 = 6
#> 2 Var 2-Var1 1 5 5 - 1 = 4
#> 3 (Var 2-(Var 2-Var1))/Var 2 1 5 (5 - (5 - 1))/5 = 0.2
由reprex 包于 2022-11-07 創建(v2.0.1)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/529086.html
標籤:r数据框dplyr数据表
