我知道这是一个非常通用的标题,但请耐心等待,这更多是关于数据操作而不是数据清理。
我的数据集是1分钟的降水数据。
请允许我设置虚拟数据:
a<-data.frame(matrix(c("00:00", "00:01","00:02", "00:03",
"00:04","00:05","00:06","00:07","00:08","00:09","00:10",
"00:11","00:12", 1.2, 1.4 ,1.4, 1.5, 0.7, 0.8, 0.69, 1.2,
1.0, 1.3, 0.6, 0.2, 0, 0,0, 0 , 0, 0 , 0 , 96.6, 0 , 0 ,
0 , 0, 0 ,0),ncol=3))
names(a)<-c("time","day1","day2")
a$time<-as.POSIXct(a$time, format="%Y%m%d %H:%M")
现在,数据框现在看起来像这样
time day1 day2
1 2018-06-06 00:00:00 1.2 0
2 2018-06-06 00:01:00 1.4 0
3 2018-06-06 00:02:00 1.4 0
4 2018-06-06 00:03:00 1.5 0
5 2018-06-06 00:04:00 0.7 0
6 2018-06-06 00:05:00 0.8 0
7 2018-06-06 00:06:00 0.69 96.6
8 2018-06-06 00:07:00 1.2 0
9 2018-06-06 00:08:00 1 0
10 2018-06-06 00:09:00 1.3 0
11 2018-06-06 00:10:00 0.6 0
12 2018-06-06 00:11:00 0.2 0
13 2018-06-06 00:12:00 0 0
那里有一个奇怪的数据96.6。我想删除它。
我不能使用离群值方法,因为这是降雨量数据集,因此如果相邻行显示与第1天相似或接近的数字,则96.6mm的值是可能的,但是仅1分钟就不可能下雨96.6mm ,因此该数据可能是错误的。
但是如何指示计算机读取相邻的行,如果有超过10行的0,则删除任何值&gt; 50毫米?
注意:每分钟的平均降雨量仅约1-2毫米。答案 0 :(得分:1)
解决您的具体问题“但是如何指示计算机读取相邻的行,如果有超过10行的0,则删除任何值> 50 mm?”对于我的回答,我只看前五行。我也没有删除这些值,但如果需要,可以将它们设置为NA而不是0.
数据强>
a<-data.frame( time = c("00:00", "00:01","00:02", "00:03",
"00:04","00:05","00:06","00:07","00:08","00:09","00:10",
"00:11","00:12","00:13","00:14","00:15"),
day1 = c(1.2, 1.4 ,1.4, 1.5, 0.7, 0.8, 0.69, 1.2,
1.0, 1.3, 0.6, 0.2, 0, 0, 0, 0),
day2 = c(0,0, 0 , 0, 0 , 0 , 96.6, 0 , 0 ,
0 , 0, 0 ,0, 60, 30, 600))
time day1 day2
1 2018-06-06 00:00:00 1.20 0.0
2 2018-06-06 00:01:00 1.40 0.0
3 2018-06-06 00:02:00 1.40 0.0
4 2018-06-06 00:03:00 1.50 0.0
5 2018-06-06 00:04:00 0.70 0.0
6 2018-06-06 00:05:00 0.80 0.0
7 2018-06-06 00:06:00 0.69 96.6
8 2018-06-06 00:07:00 1.20 0.0
9 2018-06-06 00:08:00 1.00 0.0
10 2018-06-06 00:09:00 1.30 0.0
11 2018-06-06 00:10:00 0.60 0.0
12 2018-06-06 00:11:00 0.20 0.0
13 2018-06-06 00:12:00 0.00 0.0
14 2018-06-06 00:13:00 0.00 60.0
15 2018-06-06 00:14:00 0.00 30.0
16 2018-06-06 00:15:00 0.00 600.0
我在最后添加了一些数据点,看看如果连续存在两个错误(或者两个错误在一起)会发生什么。
<强>解决方案强>
library(RcppRoll)
a %>%
transmute(time, day1, day2 = ifelse(lag(roll_sumr(day2, 5)) == 0 & day2 > 50, 0, day2))
<强>输出强>
time day1 day2
1 2018-06-06 00:00:00 1.20 0
2 2018-06-06 00:01:00 1.40 0
3 2018-06-06 00:02:00 1.40 0
4 2018-06-06 00:03:00 1.50 0
5 2018-06-06 00:04:00 0.70 0
6 2018-06-06 00:05:00 0.80 0
7 2018-06-06 00:06:00 0.69 0
8 2018-06-06 00:07:00 1.20 0
9 2018-06-06 00:08:00 1.00 0
10 2018-06-06 00:09:00 1.30 0
11 2018-06-06 00:10:00 0.60 0
12 2018-06-06 00:11:00 0.20 0
13 2018-06-06 00:12:00 0.00 0
14 2018-06-06 00:13:00 0.00 30
15 2018-06-06 00:14:00 0.00 600
如果你想进行某种滚动发布,有一些事情要考虑,但你可以用这样的代码编写代码:
a %>%
transmute(time, day1,
day2 = ifelse(day2 > 3*lag(roll_sdr(day2, 5)) & !is.na(lag(roll_sdr(day2, 5))),
lag(roll_meanr(day2, 5)),
day2))
<强>输出强>
time day1 day2
1 2018-06-06 00:00:00 1.20 0
2 2018-06-06 00:01:00 1.40 0
3 2018-06-06 00:02:00 1.40 0
4 2018-06-06 00:03:00 1.50 0
5 2018-06-06 00:04:00 0.70 0
6 2018-06-06 00:05:00 0.80 0
7 2018-06-06 00:06:00 0.69 0
8 2018-06-06 00:07:00 1.20 0
9 2018-06-06 00:08:00 1.00 0
10 2018-06-06 00:09:00 1.30 0
11 2018-06-06 00:10:00 0.60 0
12 2018-06-06 00:11:00 0.20 0
13 2018-06-06 00:12:00 0.00 0
14 2018-06-06 00:13:00 0.00 0
15 2018-06-06 00:14:00 0.00 30
16 2018-06-06 00:15:00 0.00 18
您看到它找到了错误的96.6并将其更改为前5个值(即0)的平均值。对于第2天的60值,它正在做同样的事情。 30不会改变,因为它不超过前5个值的3个标准偏差。 600比前5个值大3个标准差,因此它将其更改为前5个值的平均值。您可能需要调整/迭代此过程以获得所需内容。
答案 1 :(得分:0)
您可以在基础R中使用DataContractSerializerOperationBehavior
。定义具有阈值的函数,并与diff
一起检查以查看应删除的错误。不会删除行,但错误值将接收它的先前值。
which
数据
flattenSpikes <- function(x, threshold) {
diffprev <- diff(x)
x[which(diffprev > threshold) + 1] <- x[which(diffprev > threshold)]
return(x)
}
a[,-1] <- mapply(flattenSpikes, a[,-1], 50)
a
# time day1 day2
# 1 2018-06-06 00:00:00 1.20 0
# 2 2018-06-06 00:01:00 1.40 0
# 3 2018-06-06 00:02:00 1.40 0
# 4 2018-06-06 00:03:00 1.50 0
# 5 2018-06-06 00:04:00 0.70 0
# 6 2018-06-06 00:05:00 0.80 0
# 7 2018-06-06 00:06:00 0.69 0
# 8 2018-06-06 00:07:00 1.20 0
# 9 2018-06-06 00:08:00 1.00 0
# 10 2018-06-06 00:09:00 1.30 0
# 11 2018-06-06 00:10:00 0.60 0
# 12 2018-06-06 00:11:00 0.20 0
# 13 2018-06-06 00:12:00 0.00 0