[英]How to avoid using sapply() on user defined functions in R
I am a beginner with R programming.我是 R 编程的初学者。 Recently I wrote a user-defined function as follows:
最近写了一个用户自定义的function如下:
foo <- function(x){
power <- 1:4
sum(x^power)
}
This function works fine when x is a single number.当 x 是单个数字时,此 function 工作正常。 For example, when
x = 1
, the result is 4 and when x = 10
the result is 11110. However, this function doesn't work with vectors.例如,当
x = 1
时,结果为 4,当x = 10
时,结果为 11110。但是,此 function 不适用于向量。 For example, when x <- c(1, 10)
, the result is 10102 which is not what I want.例如,当
x <- c(1, 10)
时,结果是 10102 这不是我想要的。 My desire result is a vector such as 4 11110
.我想要的结果是一个向量,例如
4 11110
。 I know this problem can be solved by using sapply()
on function or add a for-loop inside the function, but I think there might be another way to rewrite the function without using loops or "apply" functions.我知道这个问题可以通过在 function 上使用
sapply()
或在 function 中添加一个 for 循环来解决,但我认为可能有另一种方法来重写 ZC1C425268E68385D1AB4Z5074 没有循环的函数。 I have tried different ways to rewrite the function but nothing works, can somebody help me to solve the problem?我尝试了不同的方法来重写 function 但没有任何效果,有人可以帮我解决问题吗? Thanks!
谢谢!
Mathematically, a simple and more straightforward approach is to rewrite foo
function like below在数学上,一个简单直接的方法是重写
foo
function 如下
foo <- function(x) {
power <- 1:4
ifelse(x==1,max(power),x*(x**(max(power))-1)/(x-1))
}
which gives这使
> foo(c(1,10))
[1] 4 11110
I don't think there is a way to avoid any kind of implicit or explicit loop since power
is a vector and you are passing x
to it which is another vector.我认为没有办法避免任何类型的隐式或显式循环,因为
power
是一个向量,而您将x
传递给它,它是另一个向量。
Here are few options:这里有几个选项:
sapply
(which you have already figured out).sapply
(你已经想通了)。sapply(c(1, 10), foo)
#[1] 4 11110
Vectorize
where you cannot "see" the loop but it still loop beneath as it is a wrapper to mapply
.Vectorize
,您无法“看到”循环,但它仍然在下方循环,因为它是mapply
的包装器。Vectorize(foo)(c(1, 10))
#[1] 4 11110
outer
:outer
:foo <- function(x){
power <- 1:4
rowSums(outer(x, power, `^`))
}
foo(c(1, 10))
#[1] 4 11110
and obviously you can write a simple for
loop as well and pass c(1, 10)
to it.显然你也可以编写一个简单
for
循环并将c(1, 10)
传递给它。
This works:这有效:
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
Runs about 8.5x faster than using sapply(x foo)
(when foo
is a vector of length == 1,000,000).运行速度比使用
sapply(x foo)
快大约 8.5 倍(当foo
是长度 == 1,000,000 的向量时)。 It's a bit late here, so I don't know whether you could optimise the internals a little better.这里有点晚了,所以我不知道你是否可以更好地优化内部结构。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.