在multidplyr中使用dplyr::do调用带参数的函数

5
我想使用multidplyr来加速获取回归拟合的残差。我创建了一个函数,用于拟合回归模型以获取残差,该函数除了数据外,还需获取两个参数。
以下是函数内容:
func <- function(df,reg.mdl,mdl.fmla)
{
  if(reg.mdl == "linear"){
    df$resid <- lm(formula = mdl.fmla, data = df)$residuals
  } else if(reg.mdl == "poisson"){
    df$resid <- residuals(object = glm(formula = mdl.fmla,data = df,family = "poisson"),type='pearson')
  }
  return(df)
}

这里有一个数据示例,我将尝试使用 multidplyr 方法:

set.seed(1)
ds <- data.frame(group=c(rep("a",100), rep("b",100),rep("c",100)),sex=rep(sample(c("F","M"),100,replace=T),3),y=rpois(300,10))
model.formula <- as.formula("y ~ sex")
regression.model <- "poisson"

这里是 multidplyr 的方法:

ds %>% partition(group) %>% cluster_library("tidyverse") %>%
  cluster_assign_value("func", func) %>%
  do(results = func(df=.,reg.mdl=regression.model,mdl.fmla=model.formula)) %>% collect() %>% .$results %>% bind_rows()

然而,这会报错:

Error in checkForRemoteErrors(lapply(cl, recvResult)) : 
  3 nodes produced errors; first error: object 'regression.model' not found
In addition: Warning message:
group_indices_.grouped_df ignores extra arguments

我猜我从do传递参数到func的方式是错误的。

你有什么正确的方法吗?

1个回答

8

由于集群环境中没有这些对象,因此导致错误。因此,需要将变量分配给集群进程:

ds %>%
  partition(group) %>%
  cluster_library("tidyverse") %>%
  cluster_assign_value("func", func) %>%
  cluster_copy(regression.model) %>%
  cluster_copy(model.formula) %>%
  do(results = func(
    df = .,
    reg.mdl = regression.model,
    mdl.fmla = model.formula
  )) %>%
  collect() %>%
  .$results %>%
  bind_rows()

或者另一种方式(我更喜欢在链之前设置集群):
CL <- makePSOCKcluster(3)
clusterEvalQ(cl = CL, library("tidyverse"))
clusterExport(cl = CL, list("func", "regression.model", "model.formula"))

ds %>%
  partition(group, cluster = CL) %>%
  do(results = func(
    df = .,
    reg.mdl = regression.model,
    mdl.fmla = model.formula
  )) %>%
  collect() %>%
  .$results %>%
  bind_rows()

stopCluster(CL)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接