Как получить тот же результат без использования цикла for в R - PullRequest
0 голосов
/ 01 октября 2018

Я слышал, что петли в R медленные, поэтому мне было интересно, как это упростить, чтобы ускорить процесс.Я хочу вычесть 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 голосов
/ 03 октября 2018

Еще одна возможность, это должно быть очень быстро:

(connections - 1) * (connections >= 1)
0 голосов
/ 01 октября 2018

В дополнение к уже опубликованным ответам, краткий тест с результатами на моей машине (Intel Core i5-8400 2,80 ГГц, 16 ГБ ОЗУ):

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

Решение Аарона (безусловно)) самый быстрый

0 голосов
/ 01 октября 2018
> 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
0 голосов
/ 01 октября 2018

Один из способов - сохранить максимум (соединений - 1) и 0.

pmax(connections - 1, 0)
0 голосов
/ 01 октября 2018

Сначала вы скажете

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

, но, поскольку вы не хотите, чтобы отрицательные значения появлялись, лучше было бы

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

, поэтому значения 0,5 не будут установленыдо -0,5, но до 0.

...