как удалить ошибочные данные из фрейма данных в R - PullRequest
0 голосов
/ 06 июня 2018

Я знаю, что это ОЧЕНЬ общий заголовок, но имейте в виду, это больше касается манипулирования данными, чем очистки данных.

Мой набор данных представляет собой данные об осадках за 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. Я хочу удалить их.

Я не могу использовать метод выбросов, поскольку это набор данных об осадках, поэтому возможно значение 96,6 мм.если в соседних строках показано похожее или близкое число, как в день 1, но дождь в течение 96,6 мм не может быть в течение всего 1 минуты, поэтому возможно, что эти данные являются ошибкой.

Но как мне это сделать?попросите компьютер прочитать соседние ряды, и если их более 10 строк, то удалите все значения> 50 мм?

примечание: среднее значение количества осадков в минуту составляет всего около 1-2 мм.

Ответы [ 2 ]

0 голосов
/ 06 июня 2018

Отвечая на ваш конкретный вопрос «Но как я могу дать компьютеру команду читать соседние строки, и если их больше 10 строк, то удалить все значения> 50 мм?»Что касается моего ответа, я смотрю только на предыдущие 5 строк.Я также не удалил значения, но вы можете установить их на 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).Для значения 60 в день 2 он делает то же самое.30 не изменяется, потому что это не более 3 стандартных отклонений предыдущих 5 значений.600 больше, чем 3 стандартных отклонения выше предыдущих 5 значений, поэтому оно меняет его на среднее значение из предыдущих 5 значений.Возможно, вам придется настроить / повторить эту процедуру, чтобы получить то, что вы хотите.

0 голосов
/ 06 июня 2018

Вы можете использовать make diff в базе R. Определите функцию с порогом и проверьте с помощью 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

Данные

a<- structure(list(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"), day1 = c(1.2, 1.4, 1.4, 1.5, 0.7, 0.8, 0.69, 1.2, 1, 
                                                  1.3, 0.6, 0.2, 0), day2 = c(0, 0, 0, 0, 0, 0, 96.6, 0, 0, 0, 
                                                                              0, 0, 0)), .Names = c("time", "day1", "day2"), row.names = c(NA, 
                                                                                                                                           -13L), class = "data.frame")

a$time<-as.POSIXct(a$time, format="%H:%M")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...