我在尝试按小时计算平均温度时遇到了麻烦。
我有一个日期,时间(hh:mm:ss p.m./a.m。)和温度的数据框。 我需要的是按小时提取平均温度,以绘制每日温度变化。
我是R的新手,但尝试了解我所知道的:我首先尝试将小时数转换为数字,然后提取前两个字符,然后计算均值,但效果不佳。此外,我有很多文件可以分析说,与我找到的“解决方案”相比,拥有更加自动化和清洁的东西要好得多。
我认为在R中计算平均值必须是一个更好的方法,所以我一直在寻找其他帖子中的答案。不幸的是,我找不到从时间数据中提取统计数据的明确答案。
我的数据看起来像这样
date hour temperature
1 28/12/2013 13:03:01 41.572
2 28/12/2013 13:08:01 46.059
3 28/12/2013 13:13:01 48.55
4 28/12/2013 13:18:01 49.546
5 28/12/2013 13:23:01 49.546
6 28/12/2013 13:28:01 49.546
7 28/12/2013 13:33:01 50.044
8 28/12/2013 13:38:01 50.542
9 28/12/2013 13:43:01 50.542
10 28/12/2013 13:48:01 51.04
11 28/12/2013 13:53:01 51.538
12 28/12/2013 13:58:01 51.538
13 28/12/2013 14:03:01 50.542
14 28/12/2013 14:08:01 51.04
15 28/12/2013 14:13:01 51.04
16 28/12/2013 14:18:01 52.534
17 28/12/2013 14:23:01 53.031
18 28/12/2013 14:28:01 53.031
19 28/12/2013 14:33:01 53.031
20 28/12/2013 14:38:01 51.538
21 28/12/2013 14:43:01 53.031
22 28/12/2013 14:48:01 53.529
etc (24hs data)
我希望R计算每小时的平均值(不考虑分钟或秒的差异,只需按小时计算)
有什么建议吗? 非常感谢你提前!
此致 玛利亚
答案 0 :(得分:6)
将日期和小时列合并到POSIXct列中,并按小时休息时间cut()
合并:
df <- read.table(header=TRUE, stringsAsFactors=FALSE, text="
date hour temperature
28/12/2013 13:03:01 41.572
28/12/2013 13:08:01 46.059
28/12/2013 13:13:01 48.55
28/12/2013 13:18:01 49.546
28/12/2013 13:23:01 49.546
28/12/2013 13:28:01 49.546
28/12/2013 13:33:01 50.044
28/12/2013 13:38:01 50.542
28/12/2013 13:43:01 50.542
28/12/2013 13:48:01 51.04
28/12/2013 13:53:01 51.538
28/12/2013 13:58:01 51.538
28/12/2013 14:03:01 50.542
28/12/2013 14:08:01 51.04
28/12/2013 14:13:01 51.04
28/12/2013 14:18:01 52.534
28/12/2013 14:23:01 53.031
28/12/2013 14:28:01 53.031
28/12/2013 14:33:01 53.031
28/12/2013 14:38:01 51.538
28/12/2013 14:43:01 53.031
28/12/2013 14:48:01 53.529
28/12/2013 15:01:01 50.77")
df$datehour <- cut(as.POSIXct(paste(df$date, df$hour),
format="%d/%m/%Y %H:%M:%S"), breaks="hour")
head(df)
date hour temperature datehour
1 28/12/2013 13:03:01 41.572 2013-12-28 13:00:00
2 28/12/2013 13:08:01 46.059 2013-12-28 13:00:00
3 28/12/2013 13:13:01 48.550 2013-12-28 13:00:00
4 28/12/2013 13:18:01 49.546 2013-12-28 13:00:00
5 28/12/2013 13:23:01 49.546 2013-12-28 13:00:00
6 28/12/2013 13:28:01 49.546 2013-12-28 13:00:00
现在按小时列汇总:
means <- aggregate(temperature ~ datehour, df, mean)
head(means)
datehour temperature
1 2013-12-28 13:00:00 49.17192
2 2013-12-28 14:00:00 52.23470
3 2013-12-28 15:00:00 50.77000
plot(as.POSIXct(means$datehour), means$temperature, type="l", las=1,
main="Hourly Avg Temperatures", xlab="Hour", ylab="")
但是,对于时间序列数据,我喜欢使用包xts:
require(xts)
df.xts <- xts(df$temperature, as.POSIXct(paste(df$date, df$hour),
format="%d/%m/%Y %H:%M:%S"))
head(df.xts)
[,1]
2013-12-28 13:03:01 41.572
2013-12-28 13:08:01 46.059
2013-12-28 13:13:01 48.550
2013-12-28 13:18:01 49.546
2013-12-28 13:23:01 49.546
2013-12-28 13:28:01 49.546
means <- period.apply(df.xts, endpoints(df.xts, "hours"), mean)
head(means)
[,1]
2013-12-28 13:58:01 49.17192
2013-12-28 14:48:01 52.23470
2013-12-28 15:01:01 50.77000
注意时间戳是每小时的最后一个条目。我们可以使用此函数将时间戳(向下)与小时的开头对齐:
align.time.down = function(x,n){ index(x) = index(x)-n; align.time(x,n) }
means.rounded <- align.time.down(means, 60*60)
# 2nd argument is the number of seconds to adjust/round to,
# just like function align.time()
head(means.rounded)
[,1]
2013-12-28 13:00:00 49.17192
2013-12-28 14:00:00 52.23470
2013-12-28 15:00:00 50.77000
plot(means.rounded, las=1, main="Hourly Avg Temperatures")
答案 1 :(得分:3)
如果在问题中给出样本数据和预期输出,则总是更容易。
Data.table包的解决方案
require(data.table)
data <- fread('temp.csv',sep=',') #Assuming your data is in temp.csv
#if above step not executed, convert the data frame to data.table
data <- data.table(data)
> str(data)
Classes ‘data.table’ and 'data.frame': 12 obs. of 3 variables:
$ date : chr "28/12/2013" "28/12/2013" "28/12/2013" "28/12/2013" ...
$ hour : chr "13:03:01" "13:08:01" "13:13:01" "13:18:01" ...
$ temperature: num 41.6 46.1 48.5 49.5 49.5 ...
> data
date hour temperature avg
1: 27/12/2013 13:00:00 42.99 35.78455
2: 27/12/2013 14:00:00 65.97 35.78455
3: 27/12/2013 15:00:00 63.57 35.78455
data[,list(avg=mean(temperature)),by=hour] #dataset is sorted by hour
hour avg
1: 13:00:00 42.99
2: 14:00:00 65.97
3: 15:00:00 63.57
data[,list(avg=mean(temperature)),by="date,hour"] #data set is grouped by date,then hour
date hour avg
1: 27/12/2013 13:00:00 42.99
2: 27/12/2013 14:00:00 65.97
3: 27/12/2013 15:00:00 63.57
data[,list(avg=mean(temperature)),by=list(date,hour(as.POSIXct(data$hour, format = "%H:%M:%S")))] # to group by hour only
date hour avg
1: 27/12/2013 1 29.530
2: 27/12/2013 4 65.970