【问题标题】:Interpolate NA values in one variable while using linear interpolant使用线性插值法在一个变量中插值 NA 值
【发布时间】:2020-02-09 22:17:38
【问题描述】:

尝试在数据框中插入 NA 值,并尝试使用 zoo::na.approx 但这只会返回等间距的值。

为了演示,给定数据框:

library(dplyr)
library(zoo) 
df <- data.frame(
      a = c(1,5 ,6 , 10),
      b = c(100, NA, NA, 1000)
)

试过这个:

df %>% 
  mutate(b = zoo::na.approx(b, rule = 2))

反而想得到这个:

desired_df <- data.frame(
  a = c(1, 5 ,6 , 10),
  b = c(100, 500, 600, 1000)
)

是否有现成的函数可以做到这一点,或者必须使用线性插值公式编写:

【问题讨论】:

  • 您的建议给出了正确的输出。我将其发布为答案,尽管我希望可以使用 zoo 提供解决方案
  • 在 2 天内,是的 :)
  • 我使用zoo 发布了一个答案。请检查。

标签: r interpolation


【解决方案1】:

代码na.approx 不起作用的原因是它通过检查类来分派方法。如果我们检查

library(zoo)
methods('na.approx')
#[1] na.approx.default na.approx.ts*     na.approx.zoo*    na.approx.zooreg*

na.approx.default 方法是应用于 OP 数据的方法,因为它不是zoo 对象。如果我们检查源代码,这些方法的行为是不同的

na.approx.default

对于* 函数

getAnywhere('na.approx.zoo')

所以,正如另一个答案提到的,如果我们转换为适当的类,生成的输出也会有所不同,因为调度的方法是基于class

【讨论】:

    【解决方案2】:

    其实可以在zoo:

    desired_df <- as.zoo(df, order.by = df$a) %>% 
      na.approx()
    

    如您所见,您需要将数据框转换为zoo 类。

    【讨论】:

    • 这也可以在不转换为动物园的情况下工作:df %&gt;% mutate(b = na.approx(b, a))。关键是你必须有某种方式告诉它相对于 a 进行插值。如果它是一个时间索引为 a 的动物园对象,那么它知道;否则,你必须告诉它。
    【解决方案3】:
    lin_interp <- function(known, unknown) {
      # unknown object
      i1 <- !is.na(unknown)
    
      approx(x = known[i1], 
             y = unknown[i1], 
             xout = known)$y
    }
    

    提高代码可读性

    输出如你所愿:

    df %>% 
      mutate(b = lin_interp(a, b))
    

    【讨论】:

      猜你喜欢
      • 2020-07-31
      • 2020-03-13
      • 2019-11-02
      • 2011-11-03
      • 1970-01-01
      • 2023-03-22
      • 2013-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多