下面是我遇到的一个示例代码。
我定义了一个函数。输入一个数x
,输出一个向量vec
fct <- function(x){
vec = vector("numeric",3)
vec = c(1, x, x^2)
return(vec)
}
我有一个序列a = 1:10
,那么我希望将fct
应用于a
。理想情况下,它应该返回一个数字矩阵。我知道用sapply(a,fct)
可以达到目的。但是我很好奇如何使用map_*
。
我试过map(a,fct)
。它返回一个列表。
我试过map_dbl(a,fct)
。它返回了一个错误
Error: Result 1 must be a single double, not a double vector of length 3
Run `rlang::last_error()` to see where the error occurred.
那么,如何使用map_*
来实现这一点呢?
3条答案
按热度按时间ippsafx71#
map_*
函数不容易做到这一点。我建议使用最好的工具,并将其转换为已知的格式/结构。如果你使用
map_dbl
的动机是类型安全(purrr::map*
函数的一个优点),那么你可以用base R实现同样的安全性:当然,
vapply
要求您先验地知道类和返回值的长度,但如果这不是问题,那么您就很好了。此外,它通常非常快:(Note随着
a
长度的增加,性能差异几乎消失。)但是回到
map*
,你可以使用purrr
,只需要一个小的外部函数,它的性能虽然较慢,但并没有慢很多,并且随着数据的增加,差异会减少。
(The六个命令的输出是相同的。)
4smxwvx52#
sapply
返回矩阵的原因是因为它有一个参数simplify
,默认情况下是TRUE
。simplify
参数试图将结果简化为向量/矩阵。如果将参数更改为FALSE
,则会得到与lapply
或map
相同的输出。map
总是返回一个列表,而map_dbl
期望从函数返回一个数字,在您的情况下,函数返回3个数字。因此,一个选项是从map
的输出构造一个矩阵。brtdzjyr3#
a %>% map(fct) %>% reduce(cbind)
返回矩阵。