【问题标题】:Migrate a function from mapply to tibble rowwise将函数从 mapply 迁移到 tibble rowwise
【发布时间】:2017-10-31 00:19:47
【问题描述】:

如果需要将用户定义的函数从与mapply 一起使用转换为与tibble 一起使用rowwise 所需的任何提示或咒语,我将不胜感激。

这个最小的可重现示例基于问题described here

具体来说,我有一个调用uniroot 的函数,它与mapply 配合得很好。 但是,它在与tibble/data-frame 一起使用时会中断。

values <- tibble(a=1:3, b=4:6)
class(values)

f_1 <- function(a, x = x_default, b = b_default, y = y_default, ...){
  x - a
}

f_2 <- function(a, x, b, y){
  value_a   <- uniroot(f_1, lower=-b*100, upper=b * 100, extendInt="no", tol=0.0001, trace = 20, maxiter=1000, check.conv=TRUE,
                          x=x, b=b, y=y)
}

newCF <- partial(f_2, x=10 , y=15)
values %>% 
  mutate( newCF( a = values$a, b = values$b ) )

x=10
y=15
mapply( f_2, values$a, x=x, values$b, y=y )

mapply 的结果是:

> mapply( f_2, values$a, x=x, values$b, y=y )
       [,1] [,2] [,3]
root       10   10   10
f.root     0    0    0
iter       1    1    1
init.it    NA   NA   NA
estim.prec 410  510  610

使用tibble的结果是:

> values %>%
+   mutate( newCF( a = values$a, b = values$b ) )
Error in mutate_impl(.data, dots) :
  Evaluation error: f() values at end points not of opposite sign.
In addition: Warning messages:
1: In if (is.na(f.lower)) stop("f.lower = f(lower) is NA") :
  the condition has length > 1 and only the first element will be used
2: In if (is.na(f.upper)) stop("f.upper = f(upper) is NA") :
  the condition has length > 1 and only the first element will be used
7: doTryCatch(return(expr), name, parentenv, handler)
6: tryCatchOne(expr, names, parentenv, handlers[[1L]])
5: tryCatchList(expr, classes, parentenv, handlers)
4: tryCatch(.External2(C_zeroin2, function(arg) f(arg, ...), lower,
       upper, f.lower, f.upper, tol, as.integer(maxiter)), warning = function(w) w)
3: uniroot(f_1, lower = -b * 100, upper = b * 100, extendInt = "no",
       tol = tolerance, trace = 20, maxiter = 1000, check.conv = TRUE,
       x = x, b = b, y = y) at #2
2: (function (a, x, b, y)
   {
       value_a <- uniroot(f_1, lower = -b * 100, upper = b * 100,
           extendInt = "no", tol = tolerance, trace = 20, maxiter = 1000,
           check.conv = TRUE, x = x, b = b, y = y)
   })(dots[[1L]][[1L]], x = dots[[2L]][[1L]], dots[[3L]][[1L]],
       y = dots[[4L]][[1L]])

【问题讨论】:

  • rowwise() 会导致相当严重的性能损失。我不想解析双重问题问题,而是查看purrr 包和各种“2”或“p”包,以在 tidyverse 上下文中处理超过 2 个或更多向量/列表的迭代。
  • 感谢@hrbrmstr 引导我找到我发布的解决方案。

标签: r mapply tibble


【解决方案1】:

解决方案去掉了partial的使用,如下:

library(purr)
values %>% 
  bind_cols(pmap_df(list(a=.$a, b=.$b), f_2, x=10 , y=15))

希望对某人有所帮助。

【讨论】:

  • 干得好! (现在等待几天才能接受自己的答案很痛苦:-)
  • 是的,不确定要多长时间才能编辑答案,因为现在看来 list(a=values$a,...) 并缩写为 list(a=.$a,...) 在没有 bind_cols(...) 的情况下还不能让它工作但是致力于此。再次感谢您的提示。
猜你喜欢
  • 2020-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-17
  • 2021-06-27
  • 2017-12-14
相关资源
最近更新 更多