在R中的条件下找到多行的最大值

find maximum value for multiple rows on condition in R

我遇到了以下问题。我需要跟踪每个 ID 在系列中每次测量前后 3 小时内的 crpgluc 的最大值。在过去的几个月里,我尝试了不同的解决方案,但未能解决这个问题。我有一个如下所示的数据集:

ID  crp gluc hour
1   5   300  0.3
1   2   NA   0.9
1   NA  89   1.2
1   9   NA   4
1   NA  100  7.1
2   0   NA   0.3
2   NA  50   1
2   NA  70   2.2
2   1   80   5

结果应该是:

ID  crp gluc hours  maxCrp  MaxGluc
1   5   300  0.3    5       300
1   2   NA   0.9    5       300
1   NA  89   1.2    9       300
1   9   NA   4      9       89
1   NA  100  7.1    NA      100
2   0   NA   0.3    0       70
2   NA  50   1      0       70
2   NA  70   2.2    1       80
2   1   80   5      1       80

提前谢谢你, 埃里克

为此使用像 mutate 这样的酷 R 工具很诱人,而且通常很有用,但由于您的问题非常具体,我更喜欢使用 for 循环和清晰的语句来实现您的要求的每个部分。 以下是我的做法:

df1 <- data.frame(ID=c(1,1,1,1,1,2,2,2,2),crp=c(5,2,NA,9,NA,0,NA,NA,1),gluc=c(300,NA,89,NA,100,NA,50,70,80),hour=c(0.3,0.9,1.2,4,7.1,.3,1,2.2,5)) 
df1$maxCrp <- 0
df1$MaxGluc <- 0
clinical_window <- 3
for (i in 1:nrow(df1)){
  mask <- (df1$ID == df1$ID[i]) & (abs(df1$hour-df1$hour[i]) < clinical_window)
  df1$maxCrp[i] <- max(df1$crp[mask], na.rm=TRUE)
  df1$MaxGluc[i] <- max(df1$gluc[mask], na.rm=TRUE)
}
df1$maxCrp[is.infinite(df1$maxCrp)] <- NA
df1$MaxGluc[is.infinite(df1$MaxGluc)] <- NA

此代码会在缺少数据的地方发出警告。

如果有兴趣,您可以使用 data.table 和以下方法。

这包括非等值自连接,包括 crpglucmax 值,基于介于 +/- 3 之间的 hour 值小时。

tmp 临时 data.table 与 max 结果合并回原始数据。

带有 lapply 的最后一行是 from here 作为从数据 table 中删除无限值的一种方法。

library(data.table)

setDT(dt)

tmp <- dt[dt[, .(ID, hour, lower = hour - 3, upper = hour + 3)]
   , on = .(ID = ID, hour >= lower, hour <= upper)
   , .(ID, hour, crp, gluc)
   , allow.cartesian = TRUE
][, .(maxCrp = max(crp, na.rm = T), maxGluc = max(gluc, na.rm = T))
  , by = .(ID, hour)]

dt <- dt[tmp, on = .(ID, hour)]

invisible(lapply(names(dt), 
                 function(.name) set(dt, which(is.infinite(dt[[.name]])), 
                                     j = .name, value = NA)))

dt

输出

   ID crp gluc hour maxCrp maxGluc
1:  1   5  300  0.3      5     300
2:  1   2   NA  0.9      5     300
3:  1  NA   89  1.2      9     300
4:  1   9   NA  4.0      9      89
5:  1  NA  100  7.1     NA     100
6:  2   0   NA  0.3      0      70
7:  2  NA   50  1.0      0      70
8:  2  NA   70  2.2      1      80
9:  2   1   80  5.0      1      80