我想创建一个函数,用每个元素的值除以所有其他元素的总和来替换向量的所有元素。我创建了这个函数,但我确信有更好更简单的方法来编写它:
v1=runif(10)
v2=c()
l=1:length(v1)
for(i in l){
v2=c(v2,(v1[i]/sum(v1[l[l!=i]])))
}
v1=v2
答案 0 :(得分:3)
试试这段代码:
v / (sum(v) - v)
答案 1 :(得分:1)
执行此操作的一种简单方法是使用vapply
函数(另请参阅this thread):
myfun <- function(x) {
vapply(seq_along(x), function(i) x[i] / sum(x[-i]), numeric(1))
}
myfun(1:10)
## [1] 0.01851852 0.03773585 0.05769231 0.07843137 0.10000000 0.12244898 0.14583333 0.17021277 0.19565217 0.22222222
for
- 循环在R中通常很慢且笨拙,所以如果没有必要,最好避免。但是,即使您出于某些原因需要for
- 循环,也可以进行小的改进:
forfun <- function(x) {
out <- numeric() # you know in advance that it will be a numeric vector
for(i in seq_along(x)) {
# R treats everything as a vector, so you can assign values
# to every i-th element of any vector (even the empty one)
# while concatenating c(x, x[i] / sum(x[-i])) slows things
out[i] <- x[i] / sum(x[-i])
}
out
}
现在,让我们比较效果(forfun1
是您的初始代码,forfun2
是带有for
的代码 - 循环但经过更正,myfun
是vapply
版本):
> benchmark(forfun1(runif(1000)), forfun2(runif(1000)), myfun(runif(1000)))
test replications elapsed relative user.self sys.self user.child sys.child
1 forfun1(runif(1000)) 100 1.46 1.207 1.47 0 NA NA
2 forfun2(runif(1000)) 100 1.30 1.074 1.29 0 NA NA
3 myfun(runif(1000)) 100 1.21 1.000 1.20 0 NA NA
正如您所看到的,不仅是代码的简单性,还有它的性能。