ISSUE ---------
我有数千个时间序列文件(.csv),其中包含20-50年之间的间歇数据(见df)。每个文件包含date_time和一个度量(温度)。数据是每小时的,没有测量的地方有一个"NA"。
>df
date_time temp
01/05/1943 11:00 5.2
01/05/1943 12:00 5.2
01/05/1943 13:00 5.8
01/05/1943 14:00 NA
01/05/1943 15:00 NA
01/05/1943 16:00 5.8
01/05/1943 17:00 5.8
01/05/1943 18:00 6.3
我需要检查这些文件,看看它们是否有足够的数据密度。即NA与数据值的比率不会太高。要做到这一点,我有三个条件,必须检查每个文件:
- 确保一天中不超过10%的时间是NA的
- 确保一个月内NA的天数不超过10%
- 确保连续3年的数据有有效的日期和月份。
每个标准必须依次满足,如果文件不符合要求,那么我必须创建一个不符合标准的文件的数据框架(或任何列表)。
问题 --------
我想问问社区如何处理这个问题。我考虑了嵌套if循环的价值,以及使用sqldf、plyr、aggregate甚至dplyr。但我不知道最简单的方法是什么。任何示例代码或建议将非常感激。
我想这对你有用。这些将在第二天、一个月或3年内每小时检查一次NA。没有测试,因为我不喜欢编造数据来测试它。这些函数应该吐出相应时间段内NA的数量。因此,对于函数checkdays,如果它返回的值大于2.4,那么根据您的10%规则,您会遇到问题。对于72个月和3年期间,您希望值小于2628。请再次检查这些功能。顺便说一下,这些函数假定您的NA数据在第2列中。欢呼。
checkdays <- function(data){
countNA=NULL
for(i in 1:(length(data[,2])-23)){
nadata=data[i:(i+23),2]
countNA[i]=length(nadata[is.na(nadata)])}
return(countNA)
}
checkmonth <- function(data){
countNA=NULL
for(i in 1:(length(data[,2])-719)){
nadata=data[i:(i+719),2]
countNA[i]=length(nadata[is.na(nadata)])}
return(countNA)
}
check3years <- function(data){
countNA=NULL
for(i in 1:(length(data[,2])-26279)){
nadata=data[i:(i+26279),2]
countNA[i]=length(nadata[is.na(nadata)])}
return(countNA)
}
所以我最终测试了这些。他们为我工作。这里是一个数据集一年的系统时间。所以我想你不会有问题的。
> system.time(checkdays(RM_W1))
user system elapsed
0.38 0.00 0.37
> system.time(checkmonth(RM_W1))
user system elapsed
0.62 0.00 0.62
优化:我花时间用你上面发布的数据运行这些函数,结果并不好。For循环是危险的,因为它们在小数据集上工作得很好,但随着数据集变大,即如果它们没有正确构建,它们的速度就会呈指数级下降。我无法用您的数据报告上述功能的系统时间(它从未完成),但我等待了大约30分钟。在阅读了这篇很棒的文章后,加快了R中的循环操作,我重写了函数,使其更快。通过最小化循环中发生的事情的数量和预分配内存,您可以真正加快速度。你需要像checkdays(df[,2])
那样调用函数,但这样会更快。
checkdays <- function(data){
countNA=numeric(length(data)-23)
for(i in 1:(length(data)-23)){
nadata=data[i:(i+23)]
countNA[i]=length(nadata[is.na(nadata)])}
return(countNA)
}
> system.time(checkdays(df[,2]))
user system elapsed
4.41 0.00 4.41
我相信这些应该足够满足你的需要了。至于闰年,你应该能够修改我在评论中提到的优化功能。但是,请确保指定闰年数据集作为第二个数据集,而不是第二个列。