【问题标题】:How do I prevent interpolation between values where there are more than 2 missing rows of data?如何防止在缺少 2 行以上数据的值之间进行插值?
【发布时间】:2019-04-09 18:42:49
【问题描述】:

我想在 mutate_at() 中编写一个条件语句,以便 approx() 不会在缺少 2 行以上数据的值之间进行插值。

以下是数据:

dat <- data.frame(
  time = 1:10, 
  var1 = c(10, 10, 10, 12, 12, 12, 15, 15, 15, 15), 
  var2 = c( 1, NA,  3,  6, NA, NA, NA, 10,  9,  8), 
  var3 = c(10, NA, NA, 13, 14, 16, NA, 18, 19, 20)
)

这是我想要调整的代码块,它不会在值之间有超过 2 个 NA 的地方进行插值(即 var2 列中的第 5-7 行应该保持 NA 并且所有其他 NA 应该被插值价值观。

library(tidyverse)

dat_int <- dat %>%
  mutate_at(vars(c(var2, var3)),
            funs(approx(time, ., time, rule = 1, method = "linear")[["y"]]))

【问题讨论】:

  • 时间步长总是1吗?您是否只是用周围值的平均值填充缺失值?
  • @MrFlick,不,时间步长并不总是一个。这是一个简化的例子。

标签: r dplyr tidyverse


【解决方案1】:

第 1 步:创建一个函数 consecutiveNA,它可以根据阈值(由参数 len 指定)识别向量中的连续 NA

consecutiveNA <- function(x, len = 2){
  rl <- rle(is.na(x))
  logi <- rl$lengths >= len & rl$values
  rl$values <- logi
  inver <- inverse.rle(rl)
  return(inver)
}

第 2 步:将 approx 函数应用于目标列(如您所做的那样)。

library(tidyverse)

dat_int <- dat %>%
  mutate_at(vars(c(var2, var3)),
            funs(approx(time, ., time, rule = 1, method = "linear")[["y"]]))

第 3 步:将consecutiveNA 函数应用于dat 中的所有列,并将结果转换为矩阵。

m_NA <- map(dat, consecutiveNA, len = 2) %>%
  as.data.frame() %>%
  as.matrix()

第四步:基于m_NA,将dat_int中的NA替换成TRUE,就完成了。您可以将len 更改为3 或其他数字,看看是否有效。

dat_int[m_NA] <- NA

dat_int
#    time var1 var2 var3
# 1     1   10    1   10
# 2     2   10    2   NA
# 3     3   10    3   NA
# 4     4   12    6   13
# 5     5   12   NA   14
# 6     6   12   NA   16
# 7     7   15   NA   17
# 8     8   15   10   18
# 9     9   15    9   19
# 10   10   15    8   20

【讨论】:

  • 以上是一个简化的例子。我的实际数据集的列结构更像是 id1、id2、timestamp、var1、var2、var3(即时间戳列之前有重要列)。当我应用上面的代码时,在运行代码的最后一行dat_int[m_NA] &lt;- NA 时出现错误“[&lt;-.data.frame(*tmp*, m_NA, value = NA) 中的错误:替换中不支持的矩阵索引”。我认为这是因为额外的非数字列。有没有一种简单的方法来调整你的代码来处理这个问题?或者我应该问一个关于 SO 的新问题?
  • @DKincaid 我今天没有太多时间研究你的问题。您如何发布一个带有可重复示例的新问题并让其他人看一看?我可能会在这周晚些时候看看。
  • 会的。谢谢!
猜你喜欢
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 2016-10-04
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
  • 2021-07-07
  • 1970-01-01
相关资源
最近更新 更多