【问题标题】:Calculate Max value contained between the beginning of the day and the min value计算包含在一天开始和最小值之间的最大值
【发布时间】:2013-10-03 09:07:36
【问题描述】:

我需要计算一天开始到最小值发生时刻之间的最大值。这是我的一天一棵树数据集的玩具示例:

             TIMESTAMP year DOY ring dendro diameter
1  2013-05-02 00:00:00 2013 122    1      1     3405
2  2013-05-02 00:15:00 2013 122    1      1     3317
3  2013-05-02 00:30:00 2013 122    1      1     3217
4  2013-05-02 00:45:00 2013 122    1      1     3026
5  2013-05-02 01:00:00 2013 122    1      1     4438
6  2013-05-03 00:00:00 2013 123    1      1     3444
7  2013-05-03 00:15:00 2013 123    1      1     3410
8  2013-05-03 00:30:30 2013 123    1      1     3168
9  2013-05-03 00:45:00 2013 123    1      1     3373
10 2013-05-02 00:00:00 2013 122    2      4     5590
11 2013-05-02 00:15:00 2013 122    2      4     5602
12 2013-05-02 00:30:00 2013 122    2      4     5515
13 2013-05-02 00:45:00 2013 122    2      4     4509
14 2013-05-02 01:00:00 2013 122    2      4     5566
15 2013-05-02 01:15:00 2013 122    2      4     6529

首先,我计算了每个 dendro(包含在一个环中)中每一天(DOY= 一年中的哪一天)的 MIN 直径,同时获得了该最小值发生的时间:

library(plyr)
dailymin <- ddply(datamelt, .(year, DOY, ring, dendro),function(x)x[which.min(x$diameter), ])

现在,我的问题是我想计算每天的 MAX 直径。但是,有时 de 最大值出现在最小值之后。我只对最小值之前包含的最大值感兴趣。如果它发生在最小值之后,我对总最大值不感兴趣。因此,我需要从一天开始 (00:00:00) 到最小直径的时间间隔内包含的最大值(对于每一天)。就像我对最小值所做的那样,我还需要知道最大值发生在什么时间。这就是我想从以前的df中得到的:

  year DOY ring dendro             timeMin  min             timeMax  max
1 2013 122    1      1 2013-05-02 00:45:00 3026 2013-05-02 00:00:00 3405
2 2013 123    1      1 2013-05-03 00:30:00 3168 2013-05-03 00:00:00 3444
3 2013 122    2      4 2013-05-02 00:45:00 4509 2013-05-02 00:00:15 5602

如您所见,最小值是实际的最小值。但是,我想要的最大值不是一天的最大值,它是一天开始和最小值之间发生的最大值。 我的第一次尝试,不成功,返回当天的最大值,即使它超出了所需的时间间隔:

    dailymax <- ddply(datamelt, .(year, DOY, ring, dendro),
function(x)x[which.max(x$diameter[1:which.min(datamelt$diameter)]), ]) 

有什么想法吗?

【问题讨论】:

  • 我认为如果您提供三到四天的示例数据以显示所需的结果,您的问题可能会得到澄清。也许每天只提供五行数据。
  • 感谢您的建议。发布更新
  • 我认为一个更好的玩具示例会省略行名并删除常量变量(年份、DOY、环、dendro)或创建一些变化(因为我们应该按它们分组)。
  • 请提供dput版本的数据。

标签: r time grouping aggregate plyr


【解决方案1】:

在data.table中,你可以写:

DT[,{
  istar <- which.min(diameter)
  list(
    dmin=diameter[istar],
    prevmax=max(diameter[1:istar])
)},by='year,DOY,ring,dendro']

#    year DOY ring dendro dmin prevmax
# 1: 2013 242    6      8  470   477.2

我假设你的**ply也可以写出类似的函数

EDIT1: DT 来自哪里...

require(data.table)
DT <- data.table(header=TRUE, text='
date TIMESTAMP year DOY ring dendro diameter
1928419 2013-08-30 00:00:00 2013 242    6      8    471.5
1928420 2013-08-30 01:30:00 2013 242    6      8    477.2
1928421 2013-08-30 03:00:00 2013 242    6      8    474.7
1928422 2013-08-30 04:30:00 2013 242    6      8    470.0
1928423 2013-08-30 06:00:00 2013 242    6      8    475.6
1928424 2013-08-30 08:30:00 2013 242    6      8    478.7')

您的“TIMESTAMP”中有一个空格,因此我将其分为两列,第一列称为“日期”。如果您愿意,可以将它们粘贴在一起。下次,您可以考虑制作一个“可重现的示例”,如下所述:How to make a great R reproducible example?

EDIT2:对于最大值和最小值的时间:

DT[,{
  istar   <- which.min(diameter)
  istar2  <- which.max(diameter[1:istar])
  list(
    dmin     = diameter[istar],
    tmin     = TIMESTAMP[istar],
    dmax     = diameter[istar2],
    tmax     = TIMESTAMP[istar2]
)},by='year,DOY,ring,dendro']

#    year DOY ring dendro dmin     tmin  dmax     tmax
# 1: 2013 242    6      8  470 04:30:00 477.2 01:30:00

正如 EDIT1 中所述,我没有将您的 TIMESTAMP 变量的两个部分都放在一个列中,因为您没有以这种方式提供它们。要添加更多列,只需在上面的list() 中添加新表达式。代码背后的想法是 {} 表达式是一个代码块,您可以在其中使用与每个 year,DOY,ring,dendro 组合相关联的数据块中的变量并返回新列的列表。

【讨论】:

  • 我对data.table不熟悉。当我使用你的功能时,我得到了这个:Error in [.data.frame(datamelt, , { : unused argument (by = "year,DOY,ring,dendro”) 另外。如何获得所需示例中的最大值和最小值的时间?
  • @fede_luppi 哦,对不起,我已经对其进行了编辑,以包括如何将您的数据读入 DT 的说明;以及如何添加您在问题中提到的时间最小值和最大值。我认为如果你运行require(data.table) 然后DT &lt;- data.table(datamelt),这个错误就会消失。我很惊讶还没有人回答plyr...
猜你喜欢
  • 2020-12-23
  • 1970-01-01
  • 2021-06-03
  • 2020-04-30
  • 1970-01-01
  • 2015-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多