将不同的函数应用于数据框的列,按名称选择函数

bio*_*iha 5 r apply dplyr

假设我有一个包含多个列的数据框,其中一些我想要转换。列名称定义需要使用什么转换。

library(tidyverse)
set.seed(42)
df <- data.frame(A = 1:100, B = runif(n = 100, 0, 1), log10 = runif(n = 100, 10, 100), log2 = runif(n = 100, 10, 100), log1p = runif(n = 100, 10, 100), sqrt = runif(n = 100, 10, 100))
trans <- list()
trans$log10 <- log10
trans$log2 <- log2
trans$log1p <- log1p
trans$sqrt <- sqrt
Run Code Online (Sandbox Code Playgroud)

理想情况下,我想使用一个across调用,其中列名称与反式函数名称相匹配,并且转换将即时执行。所需的输出如下:

df_trans <- df %>% 
  dplyr::mutate(log10 = trans$log10(log10),
                log2 = trans$log2(log2),
                log1p = trans$log1p(log1p),
                sqrt = trans$sqrt(sqrt))
df_trans
Run Code Online (Sandbox Code Playgroud)

但是,我不想单独手动指定每个转换。在代表性示例中,我只有 4 个,但这个数字可能会有所不同,并且会明显更高,从而使手动规范变得繁琐且容易出错。

我通过将 trans 列表转换为数据框并左连接,设法将列名称与函数匹配,但随后无法调用列中的函数trans_function

trans_df <- enframe(trans, value = "trans_function")
df %>% 
  pivot_longer(cols = everything()) %>% 
  left_join(trans_df) %>% 
  dplyr::mutate(value = trans_function(value))
Run Code Online (Sandbox Code Playgroud)

错误:mutate()列有问题value
value = trans_function(value)
x 找不到函数“trans_function”

我想我要么需要找到一种从列表列中调用函数的方法,要么需要另一种将函数名称与列名称相匹配的方法。欢迎所有想法。

Ron*_*hah 4

我们可以使用cur_column()inacross来获取列名并将其用作子集trans

library(dplyr)

df %>%
  mutate(across(names(trans), ~trans[[cur_column()]](.x))) %>%
  head

#  A         B    log10     log2    log1p     sqrt
#1 1 0.9148060 1.821920 6.486402 3.998918 3.470303
#2 2 0.9370754 1.470472 5.821200 3.932046 7.496103
#3 3 0.2861395 1.469690 6.437524 2.799395 8.171007
#4 4 0.8304476 1.653261 5.639570 3.700698 6.905755
#5 5 0.6417455 1.976905 4.597484 4.500461 9.441077
#6 6 0.5190959 1.985133 5.638341 4.551289 4.440590
Run Code Online (Sandbox Code Playgroud)

将其与 的输出进行比较df_trans

head(df_trans)

#  A         B    log10     log2    log1p     sqrt
#1 1 0.9148060 1.821920 6.486402 3.998918 3.470303
#2 2 0.9370754 1.470472 5.821200 3.932046 7.496103
#3 3 0.2861395 1.469690 6.437524 2.799395 8.171007
#4 4 0.8304476 1.653261 5.639570 3.700698 6.905755
#5 5 0.6417455 1.976905 4.597484 4.500461 9.441077
#6 6 0.5190959 1.985133 5.638341 4.551289 4.440590
Run Code Online (Sandbox Code Playgroud)