计算当天开头和最小值之间包含的最大值

时间:2013-09-27 06:53:50

标签: r time grouping aggregate plyr

我需要计算当天开始时和最小值发生时的最大值。这是我的数据集一天和一个dendro的玩具示例:

             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(包含在一个戒指中)的每一天的MIN直径( DOY =一年中的一天),同时得到最小值发生的时间:< / p>

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

现在,我的问题是我想计算每天的 MAX 直径。但是,有时de max值出现在min值之后。我只对最小值之前包含的最大值感兴趣。如果在最小值之后发生,我对总最大值不感兴趣。因此,我需要在(从00:00:00开始)到最小直径的时间间隔内(每天)包含的最大值。就像我用min做的那样,我也需要知道最大值发生的时间。这就是我想要的前一个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)]), ]) 

有什么想法吗?

1 个答案:

答案 0 :(得分: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组合关联的数据块中的变量,并返回新列的列表。