Выбросы, возвращающие NA - PullRequest
       3

Выбросы, возвращающие NA

2 голосов
/ 03 августа 2020

Я использую приведенную ниже функцию для поиска выбросов с использованием 3 * sd, но в результатах я получаю выбросы и значения NA. В выбросах не должно быть значений NA?

как это исправить?

findingoutlier<- function (data, cutoff=3, na.rm=TRUE){
  sd <- sd(data, na.rm=TRUE)
  mean <- mean(data, na.rm=TRUE)
  outliers <- (data[data < mean - cutoff * sd | data > mean + cutoff * sd])
  return (outliers)
}

Ответы [ 3 ]

3 голосов
/ 03 августа 2020

Это довольно тонкий результат того, как NA сравнения обрабатываются в R.

Предположим, у вас есть значение NA в data. Тогда ваш критерий

data < mean - cutoff * sd | data > mean + cutoff * sd

оценивается как NA (т. Е. Мы не знаем, является ли недоступная точка данных выбросом или нет ...)

Что мы получим, если мы просим data[NA]? Из ?"[":

При извлечении числовой, логический или символьный индекс «NA» выбирает неизвестный элемент и, таким образом, возвращает «NA» в соответствующем элементе логического, целочисленного, numeri c, сложный или символьный результат ...

(это технический способ сказать «NA in, NA out»).

Так что вам следует либо отбросить NA значения из вашего ввода (например, с na.omit() или используйте

!is.na(data) & (data < mean - cutoff * sd | data > mean + cutoff * sd)

в качестве критерия.

Я не могу придумать никаких других причин, по которым вы бы в конечном итоге получили NA на выходе (и поскольку вы не привели воспроизводимого примера , я не могу угадать, какими они будут ...)

2 голосов
/ 03 августа 2020

Вы можете легко удалить NA, используя это:

outliers <- outliers[!is.na(outliers)]

Итак, ваша функция будет выглядеть так:

findingoutlier<- function (data, cutoff=3, na.rm=TRUE){
  sd <- sd(data, na.rm=TRUE)
  mean <- mean(data, na.rm=TRUE)
  outliers <- (data[data < mean - cutoff * sd | data > mean + cutoff * sd])
  outliers <- outliers[!is.na(outliers)]
  return (outliers)
}
0 голосов
/ 03 августа 2020

Похоже, вы передаете вектор целых чисел в параметре данных. outliers <- (data[data < mean - cutoff * sd | data > mean + cutoff * sd]).

С глупым набором примеров a <- c(1, 2, 3, 4, 5, 6, 7, 8, 9) это поиск data < -3.215838 | data > 13.21584, который не находит совпадения.

Я бы по умолчанию использовал пакет для выбросы .

install.packages("outliers")
library(outliers)

values <- c(1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
outlier(values)
# prints [1] 8

Другой вариант для данных временных рядов - пакет Twitters на обнаружение аномалий

install.packages("devtools")
devtools::install_github("twitter/AnomalyDetection")
library(AnomalyDetection)

values <- c(1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
dates <- as.POSIXlt(c('2010-3-01', '2010-3-02','2010-3-03', '2010-3-04', '2010-3-05', '2010-3-06', '2010-3-07', '2010-3-08', '2010-3-09', '2010-3-10', '2010-3-11', '2010-3-12', '2010-3-13', '2010-3-14', '2010-3-15', '2010-3-16', '2010-3-17', '2010-3-18'
))
df <- data.frame(dates, values)
res = AnomalyDetectionTs(df, max_anoms=0.02, direction='both', plot=TRUE)
res$anoms
res$plot
#    timestamp anoms
# 1 2010-03-04     8

введите описание изображения здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...