Как быстро обновить значения переменных после события? - PullRequest
0 голосов
/ 27 января 2019

Я хочу обновить значения переменной o после того, как событие r произошло в год y.Решение lapply() кажется довольно медленным с> 500k строками.Поэтому в поисках более быстрого решения я попытался избежать поднабора с помощью aggregate(), это немного быстрее, но не так, как ожидалось.Есть ли более быстрый способ сделать такие вещи в base R (или, может быть, в data.table)?

Пример

# lapply
lapply(split(df2, df2$id), function(x) {
  ry <- x$y[which(x[, "r"] == 1)]
  x[x$y >= ry, "o"] <- 1
  x
})

# aggregate
df2 <- merge(df1, with(df1, aggregate(list(ry=r), by=list(id=id), 
                    function(x) y[which(x == 1)])))
lapply(split(df2, df2$id), function(x) {
  x$o[x$y >= unique(x$ry)] <- 1
  x
})
# Output for id `11`
  id   ry    y o r
1 11 2003 2005 1 0
2 11 2003 2004 1 0
3 11 2003 2003 1 1
4 11 2003 2002 0 0
5 11 2003 2001 0 0

Тест

Unit: microseconds
      expr     min      lq     mean  median       uq      max neval cld
    lapply 915.181 929.724 988.2273 934.699 943.2465 5150.221   100   b
 aggregate 790.418 803.175 844.8039 810.192 817.4635 3474.984   100  a 

Данные

df1 <- structure(list(id = c(11, 11, 11, 11, 11, 22, 22, 22, 22, 22, 
33, 33, 33, 33, 33, 44, 44, 44, 44, 44, 55, 55, 55, 55, 55), 
    y = c(2005L, 2004L, 2003L, 2002L, 2001L, 2005L, 2004L, 2003L, 
    2002L, 2001L, 2005L, 2004L, 2003L, 2002L, 2001L, 2005L, 2004L, 
    2003L, 2002L, 2001L, 2005L, 2004L, 2003L, 2002L, 2001L), 
    o = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0), r = c(0, 0, 1, 0, 0, 0, 1, 0, 0, 
    0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1)), out.attrs = list(
    dim = c(id = 5L, y = 5L, o = 1L, r = 1L), dimnames = list(
        id = c("id=11", "id=22", "id=33", "id=44", "id=55"), 
        y = c("y=2001", "y=2002", "y=2003", "y=2004", "y=2005"
        ), o = "o=0", r = "r=0")), row.names = c(NA, -25L), class = "data.frame")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...