简体   繁体   中英

How do i get the same result without using a for loop in R

I hear for loops in R are slow so I was wondering how to simplify this to speed things up. I want to subtract 1 from every element in connections, but if it is already zero, i don't want to keep subtracting and make it negative.

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

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

pmax(connections - 1, 0)

In addition to the answers that are already posted, a short benchmark with the results on my machine (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's solution is (by far) the fastest

另一种可能性,它应该非常快:

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

At first, you would say

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

but since you do not want negative values to appear, better would be

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

so values of 0.5 won't get set to -0,5, but to 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM