часть данныхI я пытаюсь вычислить среднее значение почасовых измерений (около 20 в час) из большого набора данных (данные за 4 месяца), но мне нужно удалить выбросы в час, имеющие определение 2SD от среднего почасового значения.
structure(list(YEAR = c(2018L, 2018L, 2018L, 2018L, 2018L, 2018L,
2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,
2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,
2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,
2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,
2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L), MONTH = c(1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L), DAY = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L), HOUR = c(0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L,
1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L), MINUTE = c(1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L
), SECOND = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L), Tmp = c(25.6984, 25.6967, 25.6962, 25.6962,
25.6955, 25.6949, 25.6959, 25.6944, 25.6954, 25.6954, 25.6958,
25.6958, 25.6962, 25.6967, 25.6982, 25.6976, 25.6978, 25.6977,
25.6975, 25.6979, 25.5552, 25.5577, 25.5579, 25.5573, 25.746,
25.7248, 25.7164, 25.7249, 25.7379, 25.752, 25.7502, 25.7678,
25.7805, 25.7871, 25.7863, 25.7856, 25.7948, 25.7939, 25.7953,
25.7969, 25.7982, 25.7981, 25.7972, 25.7978, 25.644, 25.6451,
25.6455, 25.6456, 25.6451, 25.6454)), row.names = c(NA, 50L), class = "data.frame")
Добавляю картинку части данных. Как видите, у меня есть столбцы, разделенные по месяцам, дням и минутам.
Не очень полезно, так как мне приходится самим вводить данные. :) Можете ли вы использовать dput()
и выложить здесь вывод? Посмотрите, как выглядят первые 3 ряда mtcars
: dput(mtcars[1:3,])
Это лучше? Это только часть данных, у меня больше столбцов ...
Часть опубликованных вами данных недостаточно вариативна, поэтому я вручную изменяю значение, чтобы создать выброс. Надеюсь, мой ответ поможет ...
Я использую данные, которые вы разместили как df
.
library(tidyverse)
# manually changing first value to create an outlier
df$Tmp[1] = 60
df %>%
group_by(HOUR) %>%
mutate(MEAN = mean(Tmp),
SD = sd(Tmp),
IsOutlier = ifelse(Tmp < MEAN-2*SD | Tmp > MEAN+2*SD, 1, 0)) %>%
ungroup()
# # A tibble: 50 x 10
# YEAR MONTH DAY HOUR MINUTE SECOND Tmp MEAN SD IsOutlier
# <int> <int> <int> <int> <int> <int> <dbl> <dbl> <dbl> <dbl>
# 1 2018 1 1 0 1 0 60 27.4 7.67 1
# 2 2018 1 1 0 1 0 25.7 27.4 7.67 0
# 3 2018 1 1 0 1 0 25.7 27.4 7.67 0
# 4 2018 1 1 0 1 0 25.7 27.4 7.67 0
# 5 2018 1 1 0 1 0 25.7 27.4 7.67 0
# 6 2018 1 1 0 1 0 25.7 27.4 7.67 0
# 7 2018 1 1 0 1 0 25.7 27.4 7.67 0
# 8 2018 1 1 0 1 0 25.7 27.4 7.67 0
# 9 2018 1 1 0 1 0 25.7 27.4 7.67 0
#10 2018 1 1 0 1 0 25.7 27.4 7.67 0
# # ... with 40 more rows
Вы можете видеть, что первая строка классифицируется как строка с выбросами, которую вы можете удалить с помощью ... %>% filter(IsOutlier == 0)
на более позднем этапе.
Я оставил созданные столбцы, чтобы посмотреть, как работает процесс.
Это сработало! Но как мне превратиться в новый фреймворк? Вторая часть (для удаления выброса) тоже не очищена ...
В ответе упоминается использование filter
.
Вы можете сохранить весь этот процесс как df2 (ваш новый фрейм данных). Вы можете добавить эту последнюю часть в конце процесса, если хотите отфильтровать выбросы.
Да! Мне нужно было внести небольшие изменения (создать столбец с десятичными данными), но это сработало очень хорошо, большое спасибо
Рассмотрим ave
базы R (из встроенной библиотеки stats
для встроенной агрегации) для вычисления выброс:
df$outlier <- ave(df$Tmp, df$HOUR,
FUN=function(x) (x < (mean(x) - sd(x)*2)) | (x > (mean(x) + sd(x)*2)))
И затем соответственно подмножество:
subdf <- subset(df, outlier == 0)
Звучит как разумная и ясная логика, но нам нужны некоторые данные, чтобы помочь вам.