【问题标题】:Interpolate NA values in a data frame with na.approx使用 na.approx 在数据框中插入 NA 值
【发布时间】:2011-09-06 09:19:50
【问题描述】:

我正在尝试通过使用na.approx() 插值从我的数据框中删除NAs,但无法删除所有NAs。

我的数据框是 4096x4096,其中 270.15 作为无效值的标志。我需要数据在所有点上都是连续的,以提供气象模型。昨天我询问并获得了答案,关于如何根据另一个数据框替换数据框中的值。但在那之后我来到na.approx(),然后决定用NA 替换270.15 值并尝试na.approx() 来插入数据。但问题是为什么na.approx() 不能取代所有的 NA。

这就是我正在做的:

  • 使用 hdf5load 读取原始 hdf 文件
  • 子集数据框 (4094x4096)
  • 用 NA 代替标志值

    > sst4[sst4 == 270.15 ] = NA
    
  • 检查第一列(或任何其他)

    > summary(sst4[,1])
    
    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's
    271.3   276.4   285.9   285.5   292.3   302.8  1345.0
    
  • 运行 na.approx

    > sst4=na.approx(sst4,na.rm="FALSE")
    
  • 检查第一列

    > summary(sst4[,1]) 
    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's
    271.3   276.5   286.3   285.9   292.6   302.8   411.0
    

如您所见,411 NA 尚未删除。为什么?它们是否都对应于前导/结束列值?

head(sst4[,1])
[1] NA NA NA NA NA NA
tail(sst4[,1])
[1] NA NA NA NA NA NA

na.approx 是否需要在 NA 之前和之后具有有效值来进行插值?我需要设置任何其他 na.approx 选项吗?

非常感谢

【问题讨论】:

    标签: r dataframe interpolation


    【解决方案1】:

    一个可重现的小例子:

    library(zoo)
    set.seed(1)
    m <- matrix(runif(16, 0, 100), nrow = 4)
    missing_values <- sample(16, 7)
    m[missing_values] <- NA
    m
             [,1]     [,2]      [,3]     [,4]
    [1,] 26.55087 20.16819 62.911404 68.70228
    [2,] 37.21239       NA  6.178627 38.41037
    [3,]       NA       NA        NA       NA
    [4,] 90.82078 66.07978        NA       NA
    
    na.approx(m)
             [,1]     [,2]      [,3]     [,4]
    [1,] 26.55087 20.16819 62.911404 68.70228
    [2,] 37.21239 35.47206  6.178627 38.41037
    [3,] 64.01658 50.77592        NA       NA
    [4,] 90.82078 66.07978        NA       NA
    
    m[4, 4] <- 50
    na.approx(m)
             [,1]     [,2]      [,3]     [,4]
    [1,] 26.55087 20.16819 62.911404 68.70228
    [2,] 37.21239 35.47206  6.178627 38.41037
    [3,] 64.01658 50.77592        NA 44.20519
    [4,] 90.82078 66.07978        NA 50.00000
    

    是的,看起来您确实需要知道列的开始/结束值,否则插值不起作用。你能猜出你的边界值吗?

    另一个编辑:因此,默认情况下,您需要知道列的开始值和结束值。然而,通过传递rule = 2 可以让na.approx 始终填写空白。请参阅菲利克斯的回答。根据 Gabor 的评论,您还可以使用 na.fill 提供默认值。最后,您可以在两个方向上插值边界条件(见下文)或猜测边界条件。


    编辑:进一步的想法。由于na.approx 仅在列中进行插值,并且您的数据是空间的,因此在行中进行插值可能也很有用。然后你可以取平均值。

    当整列都是NAna.approx 失败,因此我们创建了一个更大的数据集。

    set.seed(1)
    m <- matrix(runif(64, 0, 100), nrow = 8)
    missing_values <- sample(64, 15)
    m[missing_values] <- NA
    

    双向运行na.approx

    by_col <- na.approx(m)
    by_row <- t(na.approx(t(m)))
    

    找出最好的猜测。

    default <- 50
    best_guess <- ifelse(is.na(by_row), 
      ifelse(
        is.na(by_col), 
        default,              #neither known
        by_col                #only by_col known
      ), 
      ifelse(
        is.na(by_col), 
        by_row,               #only by_row known
        (by_row + by_col) / 2 #both known
      )
    )
    

    【讨论】:

    • 谢谢里奇。我会尝试猜测边界的值;由于我的 sst 数据库的空间扩展比我将使用的 met 模型域大得多,所以我并不特别担心边界上的值。我真正需要的是在数据框的中心区域填充 NA 值。
    • 谁对我投了反对票,请你发表评论解释你不喜欢什么。如果您不提供反馈,那么我无法改进答案。
    • -1 不正确,您需要开始和结束值。端点可以按照 Felix 的回答或 na.fill 进行扩展。
    • 嗨,在这种情况下,我认为没有必要,但我可以尝试寻找结果。谢谢,你的答案对我来说是正确的。
    • @G。格洛腾迪克:得分;有明确的答案。
    【解决方案2】:

    na.approx() 遵循approx() 函数,默认情况下仅对值进行插值,而不是对其进行外插。但是,如approx() 的帮助页面中所述,您可以指定rule = 2 以推断为最接近的极值的常数值。继承 Richie Cotton 的例子:

    na.approx(m, rule = 2)
             [,1]     [,2]      [,3]     [,4]
    [1,] 26.55087 20.16819 62.911404 68.70228
    [2,] 37.21239 35.47206  6.178627 38.41037
    [3,] 64.01658 50.77592  6.178627 38.41037
    [4,] 90.82078 66.07978  6.178627 38.41037
    

    同样,您可以明确使用“最后一次观察结转”。

    na.locf(na.approx(m))
    ## "first observation carry backwards" too:
    na.locf(na.locf(na.approx(m)), fromLast = TRUE)
    

    【讨论】:

    • 感谢您的回答。它有效,但对我的数据来说可能不是一个好方法。由于数据是海面温度,因此如果 NA 数据位于海上(尽管大多数 NA 情况是在陆地点上),您通常会发现网格点之间的平滑过渡,因此推断为常数值可能不是一个好主意。跨度>
    • na.approx(... rule=2) 在手册页上光荣地没有记录!它隐藏在 70 页的 PDF 文档中。
    【解决方案3】:

    我认为你应该尝试设置na.rm=TRUE

    来自文档

    na.rm 合乎逻辑。是否应该删除领先的 NA?

    http://www.oga-lab.net/RGM2/func.php?rd_id=zoo:na.approx

    【讨论】:

    • 嗨亨里克。如果我设置 na.rm=TRUE 那么我得到一个 3818x4096 数据框,我需要保留所有 4096x4096 值。
    • 嗯,如何跳过花哨的插值并创建一个简单的循环,当看到 NA 时复制最后一个非 NA 值?
    • 我是 R 新手,将不得不寻找循环语法,我正在尝试使用基本命令进行管理。如何保留最后一个非 NA 值?如果列中的第一个值是 NA,会发生什么?另外,我更喜欢数据值之间的平滑过渡。这些是海面温度值,NA 是陆地上的点,在这些点上,满足模型需要“现实”值以避免求解方程时出现数值问题。感谢您的建议。
    • 我了解您的问题,但我想如果您从 SST 进行插值,那么土地温度将不会非常准确。也许,看看反距离加权插值并假装你的 SST 数据是点测量??
    • 我不担心准确性,因为模型知道陆地/海洋点在哪里,它只需要平滑过渡。但我会寻找反距离加权插值。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多