1

我有一个带有日期/时间列和与该日期/时间关联的值的 excel csv。我正在尝试编写一个将通过这种格式的脚本(见下文),并找到 1)每天的最大值,以及 2)当天发生最大值的时间。最好 R 会在一个新的数据框中将这两个值都返回给我。

数据看起来像这样:

         V1    V2 V3
1  5/1/2012  3:00  1
2  5/1/2012  6:00  2
3  5/1/2012  9:00  5
4  5/1/2012 12:00  3
5  5/1/2012 15:00  6
6  5/1/2012 18:00  2
7  5/1/2012 21:00  1
8  5/2/2012  0:00  2
9  5/2/2012  3:00  3
10 5/2/2012  6:00  6
11 5/2/2012  9:00  4
12 5/2/2012 12:00  6
13 5/2/2012 15:00  7
14 5/2/2012 18:00  9
15 5/2/2012 21:00  1

所以我设想的功能将返回:

1 5/1/2012 15:00 6
2 5/2/2012 18:00 9

有任何想法吗?

4

4 回答 4

2

使用 plyr 包的解决方案,我发现它非常适合此类问题。

dat.str <- '         V1    V2 V3
1  5/1/2012  3:00  1
2  5/1/2012  6:00  2
3  5/1/2012  9:00  5
4  5/1/2012 12:00  3
5  5/1/2012 15:00  6
6  5/1/2012 18:00  2
7  5/1/2012 21:00  1
8  5/2/2012  0:00  2
9  5/2/2012  3:00  3
10 5/2/2012  6:00  6
11 5/2/2012  9:00  4
12 5/2/2012 12:00  6
13 5/2/2012 15:00  7
14 5/2/2012 18:00  9
15 5/2/2012 21:00  1'

dat <- read.table(textConnection(dat.str), row.names=1, header=TRUE)

library(plyr)
ddply(dat, .(V1), function(x){
   x[which.max(x$V3), ]
})
于 2012-06-19T21:53:32.657 回答
1

如果您正在处理时间序列数据,我建议您使用时间序列类,例如zooxts

dat <- read.table(text="         V1    V2 V3
1  5/1/2012  3:00  1
2  5/1/2012  6:00  2
3  5/1/2012  9:00  5
4  5/1/2012 12:00  3
5  5/1/2012 15:00  6
6  5/1/2012 18:00  2
7  5/1/2012 21:00  1
8  5/2/2012  0:00  2
9  5/2/2012  3:00  3
10 5/2/2012  6:00  6
11 5/2/2012  9:00  4
12 5/2/2012 12:00  6
13 5/2/2012 15:00  7
14 5/2/2012 18:00  9
15 5/2/2012 21:00  1", row.names=1, header=TRUE)

require("xts")
# create an xts object
xobj <- xts(dat[, 3], order.by=as.POSIXct(paste(dat[, 1], dat[, 2]), format="%m/%d/%Y %H:%M"))

如果您只是想获得每日最大值,并且可以使用一天中的最后一个时间作为索引,则可以使用apply.daily

apply.daily(xobj, max)
#                    [,1]
#2012-05-01 21:00:00    6
#2012-05-02 21:00:00    9

为了保持它发生的时间戳,你可以这样做

do.call(rbind, lapply(split(xobj, "days"), function(x) x[which.max(x), ]))
#                    [,1]
2012-05-01 15:00:00    6
2012-05-02 18:00:00    9

split(xobj, "days")在每个元素中创建一个包含一天数据的列表。

lapply对每一天应用一个函数;在这种情况下,该函数仅返回max每天的观察结果。该lapply调用将返回一个listxts 对象。要将其转回单个 xts 对象,请使用do.call.

do.call(rbind, X)使用列表的每个元素构造对 rbind 的调用。它相当于rbind(X[[1]], X[[2]], ..., X[[n]])

于 2012-06-19T22:27:10.563 回答
1

对于另一种选择,您可以使用data.table

dat_table <- data.table(dat)

dat_table [ , list(is_max = V3==max(V3), V2, V3), by= 'V1'][which(is_max),][,is_max :=NULL]

根据@MattDowle的评论进行编辑

dat_table[, .SD[which.max(V3)], by=V1]

对于更简单的data.table解决方案。

于 2012-06-20T05:36:29.800 回答
0

干得好:

dat.str <- '         V1    V2 V3
1  5/1/2012  3:00  1
2  5/1/2012  6:00  2
3  5/1/2012  9:00  5
4  5/1/2012 12:00  3
5  5/1/2012 15:00  6
6  5/1/2012 18:00  2
7  5/1/2012 21:00  1
8  5/2/2012  0:00  2
9  5/2/2012  3:00  3
10 5/2/2012  6:00  6
11 5/2/2012  9:00  4
12 5/2/2012 12:00  6
13 5/2/2012 15:00  7
14 5/2/2012 18:00  9
15 5/2/2012 21:00  1'

dat <- read.table(textConnection(dat.str), row.names=1, header=TRUE)

do.call(rbind, 
        by(dat, INDICES=dat$V1, FUN=function(x) tail(x[order(x$V3), ], 1)))
于 2012-06-19T21:49:26.097 回答