Агрегирование данных по разнице строк в R - PullRequest
0 голосов
/ 23 января 2019

У меня есть дата-кадр, который состоит из времени, когда пациенты умерли.

Это выглядит примерно так

Time    Alive Died Lost
0       375   0    2
0.0668  373   1    9
0.3265  363   2    12
0.6439  349   0    6
0.7978  343   2    1
0.8363  340   2    2
0.8844  336   2    0
0.894   334   3    2   
0.9325  329   4    0
0.9517  325   4    1

Я хочу создать функцию, в которой она будет проверять, меньше ли время между двумя строками, чем пороговое значение.

Если, скажем, t2 - t1 <порог, то будет записано, сколько людей погибло в этом интервале и сколько было потеряно в этом интервале, и записано это. Затем он выдаст кадр данных с интервалами, превышающими пороговое значение, с добавлением соответствующих чисел. </p>

Скажи, если мой порог был 0,29 Вторая строка будет удалена, если будет зарегистрировано, что 1 человек умер, а 9 потерялись, и добавит это в первый столбец «Умеренные / потерянные»

выглядит как

Time    Alive Died Lost
0       375   1    11
0.3265  363   2    12
0.6439  349   0    6
...

Я что-то написал, но он не работает, если ему нужно добавить несколько строк. Какой лучший способ сделать это эффективно?

EDIT

aggregateTimes <- function(data, threshold = 0.04){
  indices <- (diff(data[,1]) < threshold)
  indices <- c(FALSE, indices)
  for(i in 1:(nrow(data)-1)){
    row1 <- data[i, ]
    row2 <- data[i+1, ]
    if((row2[,1] - row1[,1]) < threshold){
      newrow <- row1 + c(0,0, row2[, 3:4])
      data[i,] <- newrow
      data <- data[-(i+1),]
    }
  }
  return(data)
}

Но индексация не удалась, потому что данные имеют уменьшенное измерение?

Ответить @ Moody_Mudskipper

    Time    Alive Died Lost
0       375   1   11
0.3265  363   2    12
0.6439  349   13   11
0.9517  325   4    1

1 Ответ

0 голосов
/ 23 января 2019

Не знаю, если это именно то, что вы хотите, но это сгруппирует все записи в 0,29 временных интервалах:

require(data.table)
setDT(d)
d[, tt := floor(Time/0.29)]
d[, `:=`(newTime = first(Time), Alive = first(Alive)), keyby = tt]
d[, lapply(.SD, sum), by = .(newTime, Alive), .SDcols = c('Died', 'Lost')]
#    newTime Alive Died Lost
# 1:  0.0000   375    1   11
# 2:  0.3265   363    2   12
# 3:  0.6439   349    4    9
# 4:  0.8844   336   13    3

Или это более точно:

# create newTime indikator
newTimes <- d$Time
while(any(diff(newTimes) < 0.29)){
  i <- diff(newTimes) < 0.29
  i <- which(i)[1] + 1L
  newTimes <- newTimes[-i]
}
newTimes
# [1] 0.0000 0.3265 0.6439 0.9517

d[, tt := cumsum(Time %in% newTimes)] #grouping id
# adds new columns by grouping id (tt):
d[, `:=`(newTime = first(Time), Alive = first(Alive)), keyby = tt]
# sums Died and Lost by groups:
d[, lapply(.SD, sum), by = .(newTime, Alive), .SDcols = c('Died', 'Lost')]
#    newTime Alive Died Lost
# 1:  0.0000   375    1   11
# 2:  0.3265   363    2   12
# 3:  0.6439   349   13   11
# 4:  0.9517   325    4    1
...