根据每日最大值子集数据框

时间:2012-06-19 21:36:26

标签: r dataframe

我有一个带有日期/时间列的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 个答案:

答案 0 :(得分: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), ]
})

答案 1 :(得分: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调用将返回list个xts对象。把它变回来 单个xts对象,使用do.call

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

答案 2 :(得分: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解决方案。

答案 3 :(得分: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)))