【问题标题】:R: How to nicely divide all element of a vector by the sum of all the other elementR:如何很好地将向量的所有元素除以所有其他元素的总和
【发布时间】:2015-10-23 13:26:59
【问题描述】:

我想创建一个函数,用每个元素的值除以所有 其他 元素的总和来替换向量的所有元素。我创建了该函数,但我确信有更好、更简单的方法来编写它:

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

【问题讨论】:

标签: r for-loop apply lapply


【解决方案1】:

试试这个代码:

v / (sum(v) - v)

【讨论】:

  • 很好,谢谢!这确实是一种更简单、更合乎逻辑、更快捷的方式。但无论如何感谢@Tim,我发现了seq_alongvapply,这是我经常寻找的两个函数。
【解决方案2】:

一种简单的方法是使用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-loops 在 R 中通常很慢而且很笨拙,所以如果没有必要最好避免使用。但是,即使您出于某些原因需要 for-loop,也可以进行一些小的改进:

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-loop 但经过更正后的代码,myfunvapply 版本):

> 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

如您所见,这不仅关乎代码的简单性,还关乎性能。

【讨论】:

  • 谢谢。我尝试使用apply,但它仅适用于矩阵和数组,并且我缺少seq_along 函数,这将为我节省很多无用的for loop
猜你喜欢
  • 2018-05-07
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 2016-03-13
  • 1970-01-01
  • 2012-11-07
  • 1970-01-01
相关资源
最近更新 更多