如何避免在R中的用户定义函数上使用sapply()



我是R编程的初学者。最近我写了一个用户定义函数如下:

foo <- function(x){
power <- 1:4
sum(x^power)
}

当x是单个数字时,此函数工作正常。例如,当x = 1时,结果为4,而当x = 10时,结果是11110。但是,此函数不适用于向量。例如,当x <- c(1, 10)时,结果是10102,这不是我想要的。我的愿望结果是一个向量,比如4 11110。我知道这个问题可以通过在函数上使用sapply()或在函数内部添加for循环来解决,但我认为可能还有另一种方法可以在不使用循环或"for"的情况下重写函数;应用";功能。我尝试了不同的方法来重写函数,但都不起作用,有人能帮我解决这个问题吗?谢谢

从数学上讲,一种简单而直接的方法是重写foo函数,如下面的

foo <- function(x) {
power <- 1:4
ifelse(x==1,max(power),x*(x**(max(power))-1)/(x-1))
}

它给出

> foo(c(1,10))
[1]     4 11110

我不认为有任何方法可以避免任何类型的隐式或显式循环,因为power是一个向量,而你将x传递给它,它是另一个向量。

以下是几个选项:

  1. 你最好的选择是sapply(你已经想好了(
sapply(c(1, 10), foo)
#[1]     4 11110
  1. 另一种方法是在不能使用Vectorize的情况下"参见";循环,但它仍然在下面循环,因为它是CCD_ 11的包装器
Vectorize(foo)(c(1, 10))
#[1]     4 11110
  1. 使用outer
foo <- function(x){
power <- 1:4
rowSums(outer(x, power, `^`))
}
foo(c(1, 10))
#[1]     4 11110

显然,您也可以编写一个简单的for循环,并将c(1, 10)传递给它

这是有效的:

foo <- function(x, power = 1:4){

ind <- 1 + seq_along(power)
power <- matrix(rep(power, length(x)), nrow = length(x), byrow = T)
x <- as.matrix(x)

m <- cbind(x, power)
m <- m[, 1]^m[, ind]
v <- rowSums(m)

return(v)

}
foo(x = c(1, 10))
## [1]     4 11110

运行速度比使用sapply(x foo)快约8.5倍(当foo是长度==1000000的矢量时(。现在有点晚了,所以我不知道你是否可以更好地优化内部结构。

最新更新