按 R 中的行差异聚合数据帧
Aggregate dataframe by row difference in R
我有一个数据框,其中包含患者死亡的时间。
看起来像这样
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 < threshold 那么它会记录在那个时间间隔内有多少人死亡以及在那个时间间隔内失去了多少人并记录下来。然后它会给出一个间隔大于阈值的数据帧,并添加相应的数字。
假设我的阈值是 0.29
第二行将删除 1 人死亡和 9 人失踪的记录,并将其添加到第一行 Died/Lost 列
看起来像
Time Alive Died Lost
0 375 1 11
0.3265 363 2 12
0.6439 349 0 6
...
我已经写了一些东西,但如果它必须添加多行,它就会失败。
有效执行此操作的最佳方法是什么?
编辑
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
不知道这是否正是您想要的,但这将以 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
我有一个数据框,其中包含患者死亡的时间。
看起来像这样
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 < threshold 那么它会记录在那个时间间隔内有多少人死亡以及在那个时间间隔内失去了多少人并记录下来。然后它会给出一个间隔大于阈值的数据帧,并添加相应的数字。
假设我的阈值是 0.29 第二行将删除 1 人死亡和 9 人失踪的记录,并将其添加到第一行 Died/Lost 列
看起来像
Time Alive Died Lost
0 375 1 11
0.3265 363 2 12
0.6439 349 0 6
...
我已经写了一些东西,但如果它必须添加多行,它就会失败。 有效执行此操作的最佳方法是什么?
编辑
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
不知道这是否正是您想要的,但这将以 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