R 将间歇性 NA 值替换为结转的最后一个观察值 (NA.LOCF)
R Replace Intermittent NA Values With Last Observation Carried Forward (NA.LOCF)
背景
我需要根据 NA 的性质使用不同的方法来替换我的数据框中的 NA。我的数据框来自一项重复测量的研究,其中一些 Na 是受试者退出的结果,而另一些则是间歇性缺失测量的结果,定义为一个或一系列多个缺失测量,后跟一个测量值。
我将间歇性缺失测量称为间歇性 NA。
问题
我无法测试 NA 是否是间歇性缺失测量的结果,以及我应该使用什么函数来替换这些 NA。理想情况下,我会用 na.locf 方法替换这些间歇性的 NA。但我需要将 Dropout NA 替换为基线或最后观察到的值,以较大者为准。
例子
例1
这是一个干净的 NA 示例,我希望将其视为具有 na.locf 插补的间歇性 NA:
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(34,NA,NA,15,16,19,NA,12,23,31))
以及我希望最终结果如何:
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(34,34,34,15,16,19,19,12,23,31))
例2
这里是一个干净的 NA (dropout NA) 示例,我想通过之前的非 NA 观察或基线值(访问 1)估算,以最大者为准:
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(34,22,18,15,16,19,NA,NA,NA,NA))
我希望最终结果如何:
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(34,22,18,15,16,19,34,34,34,34))
例3
这是一个复杂的 NA 混合示例,需要不同的插补,这里先前的非 NA 观察值大于 dropout NA 的基线观察值(访问 1):
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(34,NA,NA,42,16,19,NA,38,NA,NA))
我需要的结果是:
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(34,34,34,42,16,19,19,38,38,38))
例4
另一个复杂的例子,其中基线观察(访问 1)大于先前的非 NA 值,用于 dropout NA:
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(40,NA,NA,42,16,19,NA,38,NA,NA))
我需要的结果是:
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(40,40,40,42,16,19,19,38,40,40))
我试过的
正如@Gregor 所建议的,当我说这将解决我的问题时,可以使用以下方法测试间歇性 NA 的存在:
mutate(is.na(value) & !is.na(lead(value))
但这并不能帮助我估算所有间歇性 NA,特别是序列 (NA1,NA2,NA3,14) 中的间歇性 NA,其中在 运行 之后只有 NA3 返回 TRUE这个测试。
我们可以使用 na.locf(..., fromLast = TRUE)
来识别尾随 NA
值,并将 pmax
与基线一起使用。我们将以一种很好的整体格式演示您问题中的示例:
# consolidate example data
dd = data.frame(
example = rep(1:3, each = 10),
visit = rep(1:10, 3),
value = c(34,NA,NA,15,16,19,NA,12,23,31,
34,22,18,15,16,19,NA,NA,NA,NA,
34,NA,NA,42,16,19,NA,38,NA,NA),
goal = c(34,34,34,15,16,19,19,12,23,31,
34,22,18,15,16,19,34,34,34,34,
34,34,34,42,16,19,19,38,38,38)
)
library(dplyr)
dd = dd %>% group_by(example) %>%
mutate(to_fill = !is.na(zoo::na.locf(value, fromLast = TRUE, na.rm = FALSE)),
result = if_else(to_fill,
zoo::na.locf(value, na.rm = FALSE),
pmax(first(value), zoo::na.locf(value, na.rm = FALSE))),
)
all(dd$goal == dd$result)
# [1] TRUE
如您所见,result
与 goal
列完美匹配。
背景
我需要根据 NA 的性质使用不同的方法来替换我的数据框中的 NA。我的数据框来自一项重复测量的研究,其中一些 Na 是受试者退出的结果,而另一些则是间歇性缺失测量的结果,定义为一个或一系列多个缺失测量,后跟一个测量值。 我将间歇性缺失测量称为间歇性 NA。
问题
我无法测试 NA 是否是间歇性缺失测量的结果,以及我应该使用什么函数来替换这些 NA。理想情况下,我会用 na.locf 方法替换这些间歇性的 NA。但我需要将 Dropout NA 替换为基线或最后观察到的值,以较大者为准。
例子
例1
这是一个干净的 NA 示例,我希望将其视为具有 na.locf 插补的间歇性 NA:
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(34,NA,NA,15,16,19,NA,12,23,31))
以及我希望最终结果如何:
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(34,34,34,15,16,19,19,12,23,31))
例2
这里是一个干净的 NA (dropout NA) 示例,我想通过之前的非 NA 观察或基线值(访问 1)估算,以最大者为准:
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(34,22,18,15,16,19,NA,NA,NA,NA))
我希望最终结果如何:
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(34,22,18,15,16,19,34,34,34,34))
例3
这是一个复杂的 NA 混合示例,需要不同的插补,这里先前的非 NA 观察值大于 dropout NA 的基线观察值(访问 1):
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(34,NA,NA,42,16,19,NA,38,NA,NA))
我需要的结果是:
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(34,34,34,42,16,19,19,38,38,38))
例4
另一个复杂的例子,其中基线观察(访问 1)大于先前的非 NA 值,用于 dropout NA:
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(40,NA,NA,42,16,19,NA,38,NA,NA))
我需要的结果是:
data.frame(visit=c(1,2,3,4,5,6,7,8,9,10),value=c(40,40,40,42,16,19,19,38,40,40))
我试过的
正如@Gregor 所建议的,当我说这将解决我的问题时,可以使用以下方法测试间歇性 NA 的存在:
mutate(is.na(value) & !is.na(lead(value))
但这并不能帮助我估算所有间歇性 NA,特别是序列 (NA1,NA2,NA3,14) 中的间歇性 NA,其中在 运行 之后只有 NA3 返回 TRUE这个测试。
我们可以使用 na.locf(..., fromLast = TRUE)
来识别尾随 NA
值,并将 pmax
与基线一起使用。我们将以一种很好的整体格式演示您问题中的示例:
# consolidate example data
dd = data.frame(
example = rep(1:3, each = 10),
visit = rep(1:10, 3),
value = c(34,NA,NA,15,16,19,NA,12,23,31,
34,22,18,15,16,19,NA,NA,NA,NA,
34,NA,NA,42,16,19,NA,38,NA,NA),
goal = c(34,34,34,15,16,19,19,12,23,31,
34,22,18,15,16,19,34,34,34,34,
34,34,34,42,16,19,19,38,38,38)
)
library(dplyr)
dd = dd %>% group_by(example) %>%
mutate(to_fill = !is.na(zoo::na.locf(value, fromLast = TRUE, na.rm = FALSE)),
result = if_else(to_fill,
zoo::na.locf(value, na.rm = FALSE),
pmax(first(value), zoo::na.locf(value, na.rm = FALSE))),
)
all(dd$goal == dd$result)
# [1] TRUE
如您所见,result
与 goal
列完美匹配。