我有一个矩阵,其中个人为行,时间点为列。矩阵中的值是受试者在每个时间点发生事件的概率。
set.seed(123)
prob_mat <- matrix(round(runif(15), 2), 5, 3,
dimnames = list(paste0('id', 1:5), c(1.2, 2.5, 3.1)))
# 1.2 2.5 3.1
# id1 0.29 0.05 0.96
# id2 0.79 0.53 0.45
# id3 0.41 0.89 0.68
# id4 0.88 0.55 0.57
# id5 0.94 0.46 0.10
我还有一个时间向量,名为
time_vec
。
time_vec <- c(1.7, 2.9, 4)
我想使用
线性插值估计每个受试者在
time_vec
中记录的时间点的概率。例如,时间点 1.7 位于 1.2 和 2.5 之间,距离 1.2 为 0.5,距离 2.5 为 0.8,因此插值概率应为
(prob_mat[, '1.2'] * 0.8 + prob_mat[, '2.5'] * 0.5) / 1.3
# id1 id2 id3 id4 id5
# 0.1976923 0.6900000 0.5946154 0.7530769 0.7553846
请注意,时间点
4
位于区间[1.2, 3.1]
之外。我们使用最接近时间的值,即 3.1
作为估计值。预期输出如下:
1.7 2.9 4
id1 0.1976923 0.6566667 0.96
id2 0.6900000 0.4766667 0.45
id3 0.5946154 0.7500000 0.68
id4 0.7530769 0.5633333 0.57
id5 0.7553846 0.2200000 0.10
我尝试过按行使用
apply()
和approx()
,但是对于大矩阵来说效率很低。
我们可以使用
approx()
来确定time_vec
在prob_mat
内的位置,然后使用取模运算符(%%
)来获取位置的小数部分。这个值正是线性插值所需的权重。
tt <- as.numeric(colnames(prob_mat))
pos <- approx(x = tt, y = seq_along(tt), xout = time_vec, rule = 2)$y
w <- pos %% 1
t(t(prob_mat[, floor(pos)]) * (1-w) + t(prob_mat[, ceiling(pos)]) * w)
# 1.2 2.5 3.1
# id1 0.1976923 0.6566667 0.96
# id2 0.6900000 0.4766667 0.45
# id3 0.5946154 0.7500000 0.68
# id4 0.7530769 0.5633333 0.57
# id5 0.7553846 0.2200000 0.10