【问题标题】:Get mean value from other rows into current row从其他行获取平均值到当前行
【发布时间】:2021-08-30 18:19:17
【问题描述】:

我有一个土壤特性数据表,其中包含不同位置和深度的值。有些值是 NA 所以我想得到考虑到上层和下层的平均值。在顶层的情况下,我会从下一层取值。

我能够创建一个列来指示每一行的上层和下层,并且我想进行自我合并。但是我完全不知道如何进行。

关于如何做到这一点的任何线索? Bellow 是一个示例 data.table 以及我想要实现的目标。该示例考虑具有 3 层的两个位置。但我有多个位置,有些位置比其他位置多。

library(data.table)

# I was able to identify which are the botton and top layers
# using a function to identify the neighboors
dt <- data.table(id = rep(c(1,2), 1, each = 3),
                 depth = c(10, 20, 30, 10, 20, 30),
                 val = c(12, 18, 11, 25, 27, 29),
                 bot_l = c(20, 30, NA, 20, 30, NA),
                 top_l = c(NA, 10, 20, NA, 10, 20))


# How can I calculate the average between top and lowe layers?
dt_desired <- data.table(id = rep(c(1,2), 1, each = 3),
                         depth = c(10, 20, 30, 10, 20, 30),
                         val = c(12, 18, 11, 25, 27, 29),
                         bot_l = c(20, 30, NA, 20, 30, NA),
                         top_l = c(NA, 10, 20, NA, 10, 20)
                         mean_top_bot = c(18, 11.5, 18, 27, 27, 27))

再解释一下:

  • mean_top_bot[1] = val[depth = 0] + val[depth = 20]。由于我在深度 0 处没有值,因此将变为 (NA + 18)/2 = 18 (rm.na = TRUE)
  • mean_top_bot[2] = val[depth=10] + val[depth=30] = (12+11)/2
  • 我手动计算了mean_top_bot 值。这就是为什么我有一些错误:facepal:

使用自合并的解决方案

通过更改by.x 和 by.y`参数,我能够将表格与自身合并。但我有一种感觉,我正在以最糟糕的方式这样做。

dt1 <- merge(dt, dt[, .SD, .SDcols = !c('bot_l', 'top_l')],
             by.x = c('id', 'bot_l'),
             by.y = c('id', 'depth'),
             all = TRUE)[order(id, depth)]

   id bot_l depth val.x top_l val.y
1:  1    20    10    12    NA    18
2:  1    30    20    18    10    11
3:  1    NA    30    11    20    NA
4:  1    10    NA    NA    NA    12
5:  2    20    10    25    NA    27
6:  2    30    20    27    10    29
7:  2    NA    30    29    20    NA
8:  2    10    NA    NA    NA    25

有没有更简单的方法来做到这一点?

【问题讨论】:

  • 这些数字在 mean_top_bot 中是否正确,即你能显示到达 18 的计算吗
  • 可能与@akrun的评论有关,但为什么两个表中的val列不一样?
  • 哎呀,我想出的示例中有错误。相应地更新了问题。使用mergeby.xby.y 参数我也得到了一些不错的结果。但我不确定这是最好的解决方案

标签: r data.table


【解决方案1】:

直接使用data.table::shift应该更容易,无需计算“top”和“bot”层。

dt <- data.table(id = rep(c(1,2), 1, each = 3),
                 depth = c(10, 20, 30, 10, 20, 30),
                 val = c(12, 18, 11, 25, 27, 29))

dt[, v := rowMeans(data.table::setDT(data.table::shift(val, 
                                                       c(1, - 1))),
                   na.rm = TRUE), 
   by = id]

相同,但使用 maggrittr :

library(magrittr)  

dt[, v := data.table::shift(val, c(1, -1)) %>% data.table::setDT() %>% rowMeans(na.rm = TRUE), 
   by = id]

上面的代码对给定深度计算前一个值和下一个值之间的平均值。我想 value 和 top/bot 层之间的差距是 1,并且数据已经按 id 和 depth 排序,如您的示例所示。

【讨论】:

  • 太好了,我会检查它是否有效,然后会回到这里。我不知道data.table::shift 函数。不确定所有位置的深度都相同,如果这会给我带来任何问题。另外,在第一个和最后一个深度会发生什么? Shift 返回 NA,na.rm = TRUE? 忽略
  • 没错,如果之前(或之后)没有值,则 shift 默认返回 NA。至于深度,是的,确实,如果它在不同位置发生变化,它不会产生任何影响,我将编辑我的评论。
  • 将值另存为新列dt[, v := rowMeans(...), by=id] 可能也很方便
  • 为了完整起见,shift()n 参数接受多个值以创建多个超前/滞后向量。因此,拨打shift() 就足够了(并采纳了弗兰克的建议):library(magrittr); dt[, mean_top_bot := shift(val, c(-1, 1)) %&gt;% setDT() %&gt;% rowMeans(na.rm = TRUE), id][]。此处使用magrittr 管道以提高可读性。
  • 谢谢你们,我会完成答案,我会保留一个没有 magrittr 的版本,以保持不添加另一个依赖项的可能性
【解决方案2】:

我花了一段时间才弄清楚,但这也可以通过 滚动平均数来解决:

dt[, mean_top_bot := 
     zoo::rollapply(val, width = list(c(-1L, 1L)), FUN = mean, partial = TRUE), id][]
   id depth val bot_l top_l mean_top_bot
1:  1    10  12    20    NA           18
2:  1    20  18    30    10         11.5
3:  1    30  11    NA    20           18
4:  2    10  25    20    NA           27
5:  2    20  27    30    10           27
6:  2    30  29    NA    20           27

zoo::rollapply() 的两个特性派上用场:

  1. width 参数也可以采用整数偏移列表。因此,list(c(-1L, 1L)) 指的是前一行和后续行的值,而省略了当前行。
  2. 使用partial = TRUE,只有范围内的索引子集被传递给FUN。例如,对于第一行,偏移量 -1 指的是超出范围的索引 0。因此,只有索引 2(偏移量 1)的值被传递给mean()。最后一行也是如此,只有倒数第二个值被传递给mean()

【讨论】:

    猜你喜欢
    • 2015-02-04
    • 1970-01-01
    • 2015-03-12
    • 1970-01-01
    • 2015-07-12
    • 2017-09-21
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多