实现此目的的一种可能方法是使用两种不同的连接:
- 加入应该不填充的列
- 与应该使用滚动连接填充的列连接
data.table 包用于此目的,因为 OP 表示性能可能对其设置至关重要。
library(data.table) # CRAN version 1.10.4
# make sure data is in correct order
setorder(setDT(DT), GUID, Hours)
# create sequence of hours for each case
Hours <- DT[, .(Hours = seq(min(Hours), max(Hours))), by = GUID]
# 1st join with columns which should not be filled
tmp <- DT[, c("GUID", "Hours", "Value", "AbnormCode")][Hours, on = c("GUID", "Hours")]
# 2nd, rolling join with columns which should be filled
result <- DT[, -c("Value", "AbnormCode")][tmp, on = .(GUID, Hours), roll = TRUE]
result
# GUID BirthYearNum GenderCode Hours Value AbnormCode
# 1: 27632200200 1949 Female 3 4.3 N
# 2: 27632200200 1949 Female 4 NA NA
# 3: 27632200200 1949 Female 5 NA NA
# 4: 27632200200 1949 Female 6 NA NA
# 5: 27632200200 1949 Female 7 NA NA
# ---
#273: 27632200200 1949 Female 275 NA NA
#274: 27632200200 1949 Female 276 NA NA
#275: 27632200200 1949 Female 277 NA NA
#276: 27632200200 1949 Female 278 NA NA
#277: 27632200200 1949 Female 279 3.0 L
请注意,该方法依赖于 GUID 作为唯一键,即假设必须为每个 GUID 创建单独的序列。
数据
由于 OP 未能提供可重现的数据,因此使用了以下数据:
library(data.table)
DT <- data.table(
GUID = "27632200200",
BirthYearNum = 1949L,
GenderCode = "Female",
Hours = c(3, 63, 111, 159, 231, 279),
Value = c(4.3, 3.8, 3.6, 3.3, 3, 3),
AbnormCode = c(rep("N", 3), rep("L", 3))
)
DT
# GUID BirthYearNum GenderCode Hours Value AbnormCode
#1: 27632200200 1949 Female 3 4.3 N
#2: 27632200200 1949 Female 63 3.8 N
#3: 27632200200 1949 Female 111 3.6 N
#4: 27632200200 1949 Female 159 3.3 L
#5: 27632200200 1949 Female 231 3.0 L
#6: 27632200200 1949 Female 279 3.0 L
请注意,HoursFromAdmitLab 已缩写为 Hours,AbnormalityCode 已缩写为 AbnormCode。