【发布时间】:2018-03-18 17:46:51
【问题描述】:
我想在数据框中的多个列上应用多个函数。我已经研究出如何将一个函数应用于数据框中的所有列,但我很难尝试使用 invoke_map 来应用函数列表。我玩过 quo 和 enquo,但我没有正确的组合(或者我猜还没有掌握)。
玩具示例设置:
library(tidyverse)
library(RcppRoll)
library(purrr)
ID <- letters[1:26]
var1 <- sample(1:100, 26, replace= T)
var2 <- sample(100:200, 26, replace= T)
temp <- cbind(ID, var1, var2) %>% data.frame()
这适用于一个功能:
roll.var <- function(name) {
label <- enquo(name)
map_df(temp[, 2:3], ~ name(.x, 5, fill= NA)) %>%
rename_all(funs(paste0(., '.', (!!label)))) %>%
cbind(temp, .)
}
test <- roll.var(roll_sdr)
这是我尝试使用 invoke_map 将函数列表应用于所选列:
roll.func <- c("roll_sdr", "roll_varr")
invoke_map(roll.var, .x= roll.func)
它返回:名称错误(.x,51,填充=NA):找不到函数“名称”
第二个问题是,在第一个示例生成的“测试”数据框中,第一个变量的名称不正确(var1.~),而第二个变量的名称是我预期的(var2.roll_sdr),可以是任何一个告诉我为什么?
任何解决方案和/或教育将不胜感激!
编辑:
结合 Mike 的解释,invoke_map 需要一个列表的列表来生成我想要的完整代码是:
library(tidyverse)
library(purrr)
library(RcppRoll)
library(plyr)
options(stringsAsFactors= F)
ID <- letters[1:26] %>% data.frame(ID= .)
var1 <- sample(1:100, 26, replace= T) %>% data.frame(var1= .)
var2 <- sample(100:200, 26, replace= T) %>% data.frame(var2= .)
temp <- bind_cols(ID, var1, var2)
roll.func <- list(list(roll_sdr, 'roll_sdr'),
list(roll_varr, 'roll_varr'))
roll.var <- function(name, vname) {
map_df(temp[, 2:3], ~ name(.x, 5, fill= NA)) %>%
rename_all(funs(paste0(., '.', vname))) %>%
cbind(temp, .)
}
df <- invoke_map(roll.var, roll.func)
## plyr statrment works much faster than purrr:reduce
df2 <- join_all(df, by= c('ID', 'var1', 'var2'))
是否可以在 roll.var 函数中添加一条语句,这样 vname 就不必在 roll.func 中重复?在函数内部以某种方式引用名称一次?我玩过 enquo 和 rlang 包,但我没有想出正确的组合。
roll.func <- list(list(roll_sdr),
list(roll_varr))
既可以作为函数调用,也可以将标签附加到变量名。
【问题讨论】: