如何从R

时间:2018-06-06 09:07:08

标签: r

我知道这是一个非常通用的标题,但请耐心等待,这更多是关于数据操作而不是数据清理。

我的数据集是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毫米。

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