【问题标题】:interpolating 2D data with data.table - filling NAs用 data.table 插值 2D 数据 - 填充 NA
【发布时间】:2020-05-26 16:30:57
【问题描述】:

我有两个数据集,时间步长 t 和高度 h,我合并了。

dataset_a <- data.table(t=rep(c(1,2,3,4,5,6,7,8,9), each=5),
                        h=rep(c(1:5)),
                        v=c(1:(5*9)))

一个有测量差距,以及我们实际测量但没有测量的值。

dataset_b <- data.table(t=rep(c(1,2,4,5,6,8,9), each=5),
                        h=rep(c(1:5)),
                        w=c(1:(5*7)))

dataset_b$w[12:20] <-0

合并:

dataset_merged <- merge(dataset_a, dataset_b, all=TRUE, by = c('t', 'h'))

现在我想填补空白。如何告诉 data.table 使用相邻值来填充像素?

dataset_merged[is.na(w), 
               w:= mean(c(the value at this h one timestep earlier, the value at this h one timestep later))]

非常感谢!

编辑 在 Bens 非常有帮助的评论之后,我不得不调整可重现的示例: 他的解决方案有效,但如果缺少“框架”数据则无效: 如果

dataset_b <- data.table(t=rep(c(2,4,5,6,8,9), each=5),
                        h=rep(c(1:5)),
                        w=c(1:(5*6)))
#removed the first timestep in this case
dataset_merged <- merge(dataset_a, dataset_b, all=TRUE, by = c('t', 'h'))


library(zoo)
dataset_merged[order(h,t)][, w := na.approx(w)] 

产量

Error in `[.data.table`(dataset_merged[order(h, t)], , `:=`(w, na.approx(w))) : 
  Supplied 44 items to be assigned to 45 items of column 'w'. The RHS length must either be 1 (single values are ok) or match the LHS length exactly. If you wish to 'recycle' the RHS please use rep() explicitly to make this intent clear to readers of your code.

将它们保留为 NA 是可以的,但我如何让函数清楚地知道这一点? 不幸的是,原始数据不在规则网格上。

【问题讨论】:

  • 嗨,本,非常感谢。看起来这个简单的解决方案可以为这个小样本完成工作。我将整夜运行实际数据。但我很有希望。如果您将其发布为答案,我可以将其标记为正确。
  • 也许你能帮我解释一下 na.approx 如何处理一个有多个 NA 的案例?当为我的数据使用您的解决方案时,我得到Error in `[.data.table`(dataset[order(height, datetime)], , `:=`(ze, na.approx(ze))) : Supplied 16885434 items to be assigned to 16888965 items of column 'ze'. The RHS length must either be 1 (single values are ok) or match the LHS length exactly. If you wish to 'recycle' the RHS please use rep() explicitly to make this intent clear to readers of your code. 由于输入与输出的值相同,我不明白这种差异可能来自哪里。

标签: r data.table interpolation


【解决方案1】:

也许可以试试这种方法。插值前按h对数据表进行排序,并将w数字化为十进制。使用approx(基数R)和组by = h

dataset_merged[order(h,t)][, w:= as.numeric(w)][, w := approx(.I, w, .I)$y, by = h]

输出

    t h  v    w
 1: 1 1  1   NA
 2: 2 1  6  1.0
 3: 3 1 11  3.5
 4: 4 1 16  6.0
 5: 5 1 21 11.0
 6: 6 1 26 16.0
 7: 7 1 31 18.5
 8: 8 1 36 21.0
 9: 9 1 41 26.0
10: 1 2  2   NA
11: 2 2  7  2.0
12: 3 2 12  4.5
13: 4 2 17  7.0
14: 5 2 22 12.0
15: 6 2 27 17.0
16: 7 2 32 19.5
17: 8 2 37 22.0
18: 9 2 42 27.0
19: 1 3  3   NA
20: 2 3  8  3.0
21: 3 3 13  5.5
22: 4 3 18  8.0
23: 5 3 23 13.0
24: 6 3 28 18.0
25: 7 3 33 20.5
26: 8 3 38 23.0
27: 9 3 43 28.0
28: 1 4  4   NA
29: 2 4  9  4.0
30: 3 4 14  6.5
31: 4 4 19  9.0
32: 5 4 24 14.0
33: 6 4 29 19.0
34: 7 4 34 21.5
35: 8 4 39 24.0
36: 9 4 44 29.0
37: 1 5  5   NA
38: 2 5 10  5.0
39: 3 5 15  7.5
40: 4 5 20 10.0
41: 5 5 25 15.0
42: 6 5 30 20.0
43: 7 5 35 22.5
44: 8 5 40 25.0
45: 9 5 45 30.0
    t h  v    w

附加(每个 OP):如果有一个组只有 NAw 值,则必须将其排除。

编辑(2020 年 5 月 28 日):为防止在少于 2 个可用于插值的值时使用 approx,您也可以尝试:

dataset_merged[order(h,t)
  ][, w:= as.numeric(w)
    ][, w := if(length(na.omit(w)) < 2) w else approx(.I, w, .I)$y, by = h]

测试用例:

dataset_b <- data.table(t=rep(c(2,4,5,6,8,9), each=5),
                        h=1:5,
                        w=1:30)

dataset_b$w[c(F,F,T,F,F)] <- NA

dataset_merged <- merge(dataset_a, dataset_b, all=TRUE, by = c('t', 'h'))

输出

    t h  v    w
 1: 1 1  1   NA
 2: 2 1  6  1.0
 3: 3 1 11  3.5
 4: 4 1 16  6.0
 5: 5 1 21 11.0
 6: 6 1 26 16.0
 7: 7 1 31 18.5
 8: 8 1 36 21.0
 9: 9 1 41 26.0
10: 1 2  2   NA
11: 2 2  7  2.0
12: 3 2 12  4.5
13: 4 2 17  7.0
14: 5 2 22 12.0
15: 6 2 27 17.0
16: 7 2 32 19.5
17: 8 2 37 22.0
18: 9 2 42 27.0
19: 1 3  3   NA
20: 2 3  8   NA
21: 3 3 13   NA
22: 4 3 18   NA
23: 5 3 23   NA
24: 6 3 28   NA
25: 7 3 33   NA
26: 8 3 38   NA
27: 9 3 43   NA
28: 1 4  4   NA
29: 2 4  9  4.0
30: 3 4 14  6.5
31: 4 4 19  9.0
32: 5 4 24 14.0
33: 6 4 29 19.0
34: 7 4 34 21.5
35: 8 4 39 24.0
36: 9 4 44 29.0
37: 1 5  5   NA
38: 2 5 10  5.0
39: 3 5 15  7.5
40: 4 5 20 10.0
41: 5 5 25 15.0
42: 6 5 30 20.0
43: 7 5 35 22.5
44: 8 5 40 25.0
45: 9 5 45 30.0
    t h  v    w

【讨论】:

  • 嗨,Ben,我尝试对我的数据实施您的解决方案,但没有成功。我以前没有和大约一起工作过。 $y 是从哪里来的,我之前没见过 .I 符号。您能否详细说明一下,以便我能理解我哪里出错了?
  • 很抱歉听到这不起作用 - 我很想知道发生了什么 - 你收到错误了吗?如果是这样,你能补充你的问题吗?如果结果不正确,您能进一步描述吗?至于approx(.I, w)是插值点坐标,.I应该是行号,xout = .I表示插值发生的同一行号。返回的$y 是作为插值结果返回的(x,y) 坐标。
  • 嗨 Ben,我收到错误 Error in approx(.I, ze, .I) : need at least two non-NA values to interpolate 有非 NA 值。由于我仍在尝试找出导致此错误的原因,因此我很难调整上面的示例。
  • 另外 - 有没有办法在你的数据子集上尝试这个,而不是全部 16M 行?另外(也),如果今天晚些时候(发布后 2 天)仍未得到答复,我可以开始 bounty 以便您的问题受到更多关注。我希望看到这对你有用。
  • 您的错误可能来自给定h 组的所有NA。如果都是NA,那么它就没有可以插值的值。让我再看看这个……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-02
  • 2017-06-02
  • 1970-01-01
  • 2022-08-18
  • 1970-01-01
  • 1970-01-01
  • 2022-08-04
相关资源
最近更新 更多