#r #outliers
#r #выбросы
Вопрос:
Я довольно новичок в R и борюсь либо с циклом повторения, либо с поиском выбросов, либо с обоими.
У меня большой, но ненадежный набор данных в виде матрицы. Я использую выбросы пакета для поиска выбросов в наборе данных, в частности, в каждой строке моей матрицы данных, однако для каждой строки есть несколько выбросов. Для поиска более одного выброса я попытался использовать цикл повторения для замены выбросов (средним значением строки) до тех пор, пока стандартное отклонение строки не окажется ниже определенного заданного значения.
replaceoutliers <- function(data, standarddeviationthreshold) {
for(k in 1:nrow(data)) {
repeat{
data[k,] <- rm.outlier(data[k,], fill=TRUE, median=FALSE, opposite=FALSE)
if(sd(data[k,]) > standarddeviationthreshold) {
break
}
}
}
View(data)
}
Функция выполняется, но заменяет только высокое значение в каждой строке. Есть ли проблема в цикле повторения? Кто-нибудь знает о пакете, который найдет и заменит несколько выбросов? До сих пор я не смог оштрафовать ни одного.
Спасибо!
Редактировать: я не могу поделиться данными, которые я использую, но это тест, который я провел: я передал функцию
data <- matrix(c(1:16)^2, nrow=4, ncol=4)
data
[,1] [,2] [,3] [,4]
[1,] 1 25 81 169
[2,] 4 36 100 196
[3,] 9 49 121 225
[4,] 16 64 144 256
replaceoutliers(data, 1)
[,1] [,2] [,3] [,4]
[1,] 1 25 81 35.66667
[2,] 4 36 100 46.66667
[3,] 9 49 121 59.66667
[4,] 16 64 144 74.66667
Итак, мы видим, что высокие значения заменяются средним значением. Однако, например, в первой строке 1 также следует заменить.
Комментарии:
1. Нормальные данные. Забыл изменить его, извините.
2. По-видимому,
rm.outlier(..., fill=TRUE)
является идемпотентным.3. Итак, если я изменю то, что я использую для идентификации выбросов, я должен быть готов?
Ответ №1:
Вам лучше использовать outlier
функцию напрямую, чтобы последовательно удалять выбросы:
replaceoutliers <- function(x, threshold) {
t(apply(data, 1, function(row) {
exclude <- rep(FALSE, length(row))
repeat {
outliers <- outlier(row[!exclude], logical=TRUE)
exclude[!exclude] <- outliers
if (sd(row[!exclude]) < threshold) break
}
row[exclude] <- mean(row)
row
}))
}
Здесь выбросы последовательно удаляются из данных и заменяются средним значением, пока не будет нарушено желаемое стандартное отклонение.
Некоторые примечания:
У вас неправильное направление для теста стандартного отклонения. Стандартное отклонение будет уменьшаться по мере замены выбросов средним значением.
outlier
находит один выброс в данных, худшее значение. Сохранение логического для удаленных значений позволяет выполнять последовательное удаление при отслеживании позиций данных.
Нет гарантии, что меньшее значение будет удалено на второй итерации. Для первой строки вы удалите 81
перед 1
удалением .
Если вы попытаетесь получить слишком низкое стандартное отклонение, тест завершится неудачно. Для этого можно было бы закодировать защиту, но я этого не сделал:
> replaceoutliers(data, 50)
[,1] [,2] [,3] [,4]
[1,] 1 25 81 69
[2,] 4 36 100 84
[3,] 9 49 101 101
[4,] 16 64 120 120
> replaceoutliers(data, 34)
[,1] [,2] [,3] [,4]
[1,] 1 25 69 69
[2,] 4 36 84 84
[3,] 9 49 101 101
[4,] 16 64 120 120
> replaceoutliers(data, 33)
Error in if (sd(row[!exclude]) < threshold) break :
missing value where TRUE/FALSE needed