我如何在R中不使用for循环的情况下获得相同的结果

时间:2018-10-01 17:44:53

标签: r for-loop optimization vector subtraction

我听说R中的for循环很慢,所以我想知道如何简化它以加快速度。我想从连接中的每个元素中减去1,但是如果它已经为零,我就不想继续减去并使其为负数。

for(i in 1:length(connections)) {
    if(connections[i] > 0) {
      connections[i] = connections[i] - 1
    }
    if(connections[i] < 0) {
      connections[i] = 0
    }
  }

5 个答案:

答案 0 :(得分:6)

一种方法是保持(连接数-1)和0的最大值。

pmax(connections - 1, 0)

答案 1 :(得分:1)

除了已经发布的答案外,还对我的计算机上的测试结果进行了简短的基准测试(Intel Core i5-8400 2.80GHz,16GB RAM):

fun1 <- function(x){
  #Subtract 1 from values > 0
  ind <- x > 0
  x[ind] <- x[ind] - 1

  #Set to values smaller than 1 to zero
  ind <- x < 0
  x[ind] <- 0

  return(x)
}

fun2 <- function(x){
  return(ifelse(x > 0, x - 1, 0))
}

fun3 <- function(x){
  return(pmax(x - 1, 0))
}

set.seed(1234)
x <- round(runif(1e7, -1, 1))

system.time(fun1(x))
#user  system elapsed
#0.17    0.03    0.20

system.time(fun2(x))
#user  system elapsed
#0.55    0.17    0.72

system.time(fun3(x))
#user  system elapsed
#0.08    0.00    0.08

Aaron的解决方案(到目前为止)是最快的

答案 2 :(得分:1)

另一种可能性,应该很快:

(connections - 1) * (connections >= 1)

答案 3 :(得分:0)

起初,您会说

ifelse( connections > 0, connections - 1, 0 )

但是由于您不希望出现负值,所以更好

ifelse( connections >= 1, connections - 1, 0 )

所以0.5的值将不会设置为-0,5,而是0。

答案 4 :(得分:0)

> set.seed(0151)
> connections <- rnorm(15)
> 
> connections 
 [1] -0.05153895  0.76573738 -0.14673959 -0.11318581 -0.39551140  0.78227595 -1.39747811 -1.01883832  0.22947586  0.67217297 -0.48455178  0.56060896  0.06615648 -1.34987612
[15] -0.24291581
> 
> connections <- ifelse(connections > 0, connections -1, 0)
> connections
 [1]  0.0000000 -0.2342626  0.0000000  0.0000000  0.0000000 -0.2177241  0.0000000  0.0000000 -0.7705241 -0.3278270  0.0000000 -0.4393910 -0.9338435  0.0000000  0.0000000