动态地将特定函数应用于不同的变量

Dynamically apply a specific function to different variables

我有一个 csv,每个变量定义一行(指的是在另一个数据集中定义的真实数据变量)。轻轻按摩后,我有一个命名向量,如 fxs.

然后我可以迭代变量,并执行适当的函数。我应该考虑另一种方法吗?也许使用 rlang::exec() and/or purrr::map_*(). I like that I can wrap the two main lines with separate tryCatch() 块可以更准确地描述是在解析函数时出错,还是在执行函数时出错。

fxs <- c(
  "Sepal.Length"   = "\(x) x *   1",
  "Sepal.Width"    = "\(x) x *  10",
  "Petal.Length"   = "\(x) x * 100"
)

d <- iris[1:5, 1:3]
for (variable in colnames(d)) {
  fx <- base::eval(base::parse(text = fxs[[variable]]))
  d[[variable]] <- fx(d[[variable]])
}
d

我认为它看起来很像 dplyr::mutate() 语句的内部。也许最好尝试将 csv 转换为传递给 ... 的语句。除了这个概念验证之外,我没有做任何事情,所以如果有人有不同的方法,我有很大的灵活性。

d |> 
  dplyr::mutate(
    Sepal.Length   = Sepal.Length *   1,
    Sepal.Width    = Sepal.Width  *  10,
    Petal.Length   = Petal.Length * 100,
  )

期望的输出:

  Sepal.Length Sepal.Width Petal.Length
1          5.1          35          140
2          4.9          30          140
3          4.7          32          130
4          4.6          31          150
5          5.0          36          140

我们可以使用 cur_column()across

内的表达式进行子集化
library(dplyr)
d %>% 
  dplyr::mutate(
    dplyr::across(
      .cols = dplyr::all_of(names(fxs)), 
      .fns  = ~ eval(parse(text = fxs[[dplyr::cur_column()]]))(.x)
    )
  )

-输出

  Sepal.Length Sepal.Width Petal.Length
1          5.1          35          140
2          4.9          30          140
3          4.7          32          130
4          4.6          31          150
5          5.0          36          140

或使用exec

library(purrr)
d %>% 
  dplyr::mutate(
    dplyr::across(
      .cols = dplyr::all_of(names(fxs)), 
      .fns  = ~ rlang::exec(
        rlang::parse_expr(fxs[[dplyr::cur_column()]]), 
        .x
      )
    )
  )

如果函数都在进行乘法运算,则创建一个命名的 vectorlist 值进行相乘,并避免 eval/parse

nm1 <- c(Sepal.Length = 1, Sepal.Width = 10, Petal.Length = 100)
d %>% 
  dplyr::mutate(
    dplyr::across(
      .cols = dplyr::all_of(names(nm1)),
      .fns  = ~ nm1[dplyr::cur_column()] * .x
    )
  )