R:将函数列表传递给另一个函数

时间:2019-05-24 15:30:48

标签: r dplyr tidyverse

是否可以将自定义函数列表传递到另一个函数的参数中?一个带有mtcars的玩具示例是将数字向上,向下四舍五入到最接近的五个,然后使用单个函数将它们合并到一个数据框中,以便:

mtcars1

enter image description here

# round_any not in dplyr
library(plyr)
library(tidyverse)

mtcars1 <- mtcars %>%
      slice(1) %>%
      select(2:7)

被转换为:

汽车

enter image description here

# Rounding Functions
round_up_decimal <- function(x) {
  round_any(x, 1, ceiling)
}

round_down_decimal <- function(x) {
  round_any(x, 1, floor)
}

round_nearest_five <- function(x) {
  round_any(x, 5)
}

# Not being used
rn_fun_list = ls(pattern = ("round_"))

new_value_gen <- function(x,y) {
  x %>%
    mutate_all(., y)  
}


mtcars2 <- new_value_gen(mtcars1, round_up_decimal)
mtcars3 <- new_value_gen(mtcars1, round_down_decimal)
mtcars4 <- new_value_gen(mtcars1, round_nearest_five)

cars <- mget(ls(pattern = "mtcars\\d$")) %>%
  map_df(I, .id = "src") %>%
  select(-1)

这可以通过每次手动调用new_value_gen函数来完成,但是它并没有真正遵循 DRY 原则。通过一个函数将rn_fun_list传递给它,是否有更优雅的方法呢?

2 个答案:

答案 0 :(得分:2)

我们可以简单地使用sapply

t(sapply(rn_fun_list, new_value_gen, x = mtcars1))
#                    cyl disp hp  drat wt qsec
# round_down_decimal 6   160  110 3    2  16  
# round_nearest_five 5   160  110 5    5  15  
# round_up_decimal   6   160  110 4    3  17  

如果您还想保留原始行,例如

t(sapply(c("identity", rn_fun_list), new_value_gen, x = mtcars1))
#                    cyl disp hp  drat wt   qsec 
# identity           6   160  110 3.9  2.62 16.46
# round_down_decimal 6   160  110 3    2    16   
# round_nearest_five 5   160  110 5    5    15   
# round_up_decimal   6   160  110 4    3    17   

答案 1 :(得分:2)

使用map

library(tidyverse)
map_df(rn_fun_list, new_value_gen, x = mtcars1)