【问题标题】:R Replace Intermittent NA Values With Last Observation Carried Forward (NA.LOCF)R 将间歇性 NA 值替换为最后一次观察结转 (NA.LOCF)
【发布时间】:2018-07-23 19:33:17
【问题描述】:

背景

我需要根据 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(辍学 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)大于 dropout NA 的先前非 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,特别是序列中的间歇性 NA (NA1,NA2,NA3,14),其中只有 NA3 在运行此测试后返回为 TRUE。

【问题讨论】:

  • 您并没有真正给出定义,但您似乎将 "intermittent NA" 定义为 NA,在其前后均具有非缺失值。它是否正确?还是你有别的定义?或者你可能不在乎有多少 NA 值,只要它们后面有非 NA ?而且,从你的例子来看,如果最后只有一个NA,那么这也被认为是间歇性的吗?
  • 如果你展示了一些你不想想要填写的NAs实例,这将是一个更好的问题,除了你已经展示了@ 987654334@ 按预期工作。
  • 至于 “如果有一种方法可以测试是否有一个 NA,然后是一个非 NA 测量,这将解决我的问题”,这行得通:@ 987654335@。但它会为最后一个值返回FALSE,因为它是NA,并且后面没有非NA值。
  • 对不起,我没有正确定义我的意思@Gregor。在这种情况下,我所说的间歇​​性 NA 是一个或一系列 NA,最终后面跟着一个非 NA 值。本质上,只要在“NA 隧道”的末端有一个非 NA 值,它们就应该被视为间歇性的 NA。如果最后一个值是 NA 并且倒数第二个值是非 NA,则无论之前的 NA 是如何处理的,这将被视为辍学的结果而不被视为间歇性 NA .我会立即尝试您的建议。
  • @Nowak 正如 Gregor 所说,如果您可以提供包含 NAs 的样本数据,您不会 想换。您的问题陈述对我来说仍然有些模糊,可能是由于非常规的术语“基本上,只要在“NA 隧道”的末端有一个非 NA 值,它们就应该被视为间歇性的 NA。”我>

标签: r dplyr zoo


【解决方案1】:

我们可以使用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

如您所见,resultgoal 列完美匹配。

【讨论】:

  • 嗨@Gregor。 fromLast = TRUE 的好想法!这就是我想做的。您是否知道如何通过在从最后一个可用的非 NA 值开始的每 3 次访问间隔后添加 +2 来估算 dropout NA?因此,如果第一个 dropout NA 发生在访问 2 并且访问 1 的观察值为 34,则: (visit = c(1,2,3,4,5,6,7,8,9,10) value = c( 34,NA,NA,NA,NA,NA,NA,NA,NA,NA)) 需要是 (visit = c(1,2,3,4,5,6,7,8,9,10) 值= c(34,34,34,36,36,36,38,38,38,40))
  • 如果您有新问题,请提出新问题。 repseq 的东西应该可以工作。
  • 我会添加一个新问题。
  • 如果你有答案,这是我的新问题 :) stackoverflow.com/questions/51506312/…
猜你喜欢
  • 1970-01-01
  • 2020-06-14
  • 2018-07-01
  • 2018-04-22
  • 1970-01-01
  • 2021-06-27
  • 1970-01-01
  • 2020-03-22
  • 2020-09-13
相关资源
最近更新 更多