我有一个数据集,其中包含血液百分比(血红蛋白水平),我感兴趣的是计算一个回顾(即。(无中心)每次病人血红蛋白水平低于7时重新启动的移动平均线。
Pt_id
代表病人id,hemoglobin_level
代表给定的血红蛋白,anemia_start
是指示给定患者血红蛋白第一次低于7的列。当anemia_start
= 1)时。
示例数据:
df <- data.frame(pt_id = c(1,1,1,1,1),
hemoglobin_level = c(8,6,5,8,7),
anemia_start = c(0,1,0,0,0))
df
pt_id hemoglobin_level anemia_start
1 1 8 0
2 1 6 1
3 1 5 0
4 1 8 0
5 1 7 0
预期产出栏为:
moving_average = c(8, 6, 5.5, 6.3, 6.5)
一旦贫血开始,移动平均线就会重新开始,所以第二个值是6,然后移动平均值继续。
我知道如何创建移动平均值(使用动物园包/滑块),但我不知道如何根据"anemia_start列“有条件地重新启动它。
谢谢你的帮助。
更多信息:
我的教授用一堆if语句在SAS中做了这件事,但是我很难把它翻译成R。
为了理解预期的输出,这是我的教授的输出(用SAS制造)的图片,我想在R中复制,我很难复制的一列是hb_gennemsnit
(=血红蛋白平均值)。
他在SAS中创建了一组中间列来生成他的代码。在丹麦语中,HB =血红蛋白(我称之为血红蛋白水平) ptnr slut
=病人数结束,ptnr start
=病人数开始,HB gennemsnit
=血红蛋白平均值。
hb_gennemsnit
列是我试图在R中复制的移动平均值列。
发布于 2022-08-24 12:33:01
使用data.table
和slider
library(data.table)
library(slider)
setDT(df)
# Helper function
adder <- function(x) {
for (i in 1:length(x)) {
if (x[i] == 0L) {
if (i != 1L) {
x[i] <- x[i-1]
} else {x[i] <- 1}
} else {
x[i] <- x[i-1] + 1
}
}
return(x)
}
# Create period index
df[, period := adder(anemia_start), by = pt_id]
# Do moving average
df[, moving_average := slide_vec(
.x = hemoglobin_level
.f = mean,
.before = Inf),
by = c("pt_id", "period")]
输出:
df
pt_id hemoglobin_level anemia_start period moving_average
1: 1 8 0 1 8.000000
2: 1 6 1 2 6.000000
3: 1 5 0 2 5.500000
4: 1 8 0 2 6.333333
5: 1 7 0 2 6.500000
6: 2 8 0 1 8.000000
7: 2 4 1 2 4.000000
8: 2 3 0 2 3.500000
9: 2 9 0 2 5.333333
10: 2 9 0 2 6.250000
OP编辑了这个问题,这样pt_id
就有了唯一的价值。在这种情况下,您可以随时随地丢弃by = pt_id
,但是最初的解决方案仍然有效。
https://stackoverflow.com/questions/73471730
复制相似问题