我有一个带有日期/时间列的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
有什么想法吗?
答案 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)
如果您正在处理时间序列数据,建议您使用时间序列类,例如zoo
或xts
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)))