Язык R - Сортировка данных по диапазонам;усреднение;игнорировать выбросы

StackOverflow https://stackoverflow.com/questions/4843194

  •  27-10-2019
  •  | 
  •  

Вопрос

Я анализирую данные с ветряной турбины, обычно это то, что я бы делал в Excel, но из-за большого объема данных требуется что-то сверхпрочное.Я никогда раньше не использовал R, поэтому я просто ищу несколько советов.

Данные состоят из 2 столбцов Скорость ветра и Сила, пока что я пришел к импорту данных из CSV-файла и сопоставил их друг с другом в виде точечных графиков.

Что я хотел бы сделать дальше, так это отсортировать данные по диапазонам;например, все данные, где Скорость ветра находится между x и y, а затем найдите среднее значение мощности, генерируемой для каждого диапазона, и постройте график полученной кривой.

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

Любые указания приветствуются.

Для тех, кому интересно, я пытаюсь создать график, подобный это.Это довольно стандартный тип графика, но, как я уже сказал, для увеличения объема данных требуется что-то более тяжелое, чем Excel.

Это было полезно?

Решение

Добавьте эту версию, аналогичную по мотивации версии @hadley's, в микс, используя аддитивную модель с адаптивным пакетом smoother using mgcv:

Сначала фиктивные данные, используемые @hadley

w_sp <- sample(seq(0, 100, 0.01), 1000)
power <- 1/(1+exp(-(w_sp -40)/5)) + rnorm(1000, sd = 0.1)
df <- data.frame(power = power, w_sp = w_sp)

Подгоните аддитивную модель, используя gam(), используя адаптивное сглаживание и выбор плавности с помощью REML

require(mgcv)
mod <- gam(power ~ s(w_sp, bs = "ad", k = 20), data = df, method = "REML")
summary(mod)

Сделайте прогноз на основе нашей модели и получите стандартные ошибки соответствия, используйте последнюю для получения приблизительного 95% доверительного интервала

x_grid <- with(df, data.frame(w_sp = seq(min(w_sp), max(w_sp), length = 100)))
pred <- predict(mod, x_grid, se.fit = TRUE)
x_grid <- within(x_grid, fit <- pred$fit)
x_grid <- within(x_grid, upr <- fit + 2 * pred$se.fit)
x_grid <- within(x_grid, lwr <- fit - 2 * pred$se.fit)

Нанесите на карту все, и Лесс подойдет для сравнения

plot(power ~ w_sp, data = df, col = "grey")
lines(fit ~ w_sp, data = x_grid, col = "red", lwd = 3)
## upper and lower confidence intervals ~95%
lines(upr ~ w_sp, data = x_grid, col = "red", lwd = 2, lty = "dashed")
lines(lwr ~ w_sp, data = x_grid, col = "red", lwd = 2, lty = "dashed")
## add loess fit from @hadley's answer
lines(x_grid$w_sp, predict(loess(power ~ w_sp, data = df), x_grid), col = "blue",
      lwd = 3)

adaptive smooth and loess fits

Другие советы

Поскольку вы больше не работаете в Excel, почему бы не использовать современную статистическую методологию, которая не требует грубой привязки данных и специальных методов для удаления выбросов:локально плавная регрессия, реализованная loess.

Используя небольшую модификацию выборочных данных csgillespie:

w_sp <- sample(seq(0, 100, 0.01), 1000)
power <- 1/(1+exp(-(w_sp -40)/5)) + rnorm(1000, sd = 0.1)

plot(w_sp, power)

x_grid <- seq(0, 100, length = 100)
lines(x_grid, predict(loess(power ~ w_sp), x_grid), col = "red", lwd = 3)

Сначала мы создадим несколько примеров данных, чтобы конкретизировать проблему:

w_sp = sample(seq(0, 100, 0.01), 1000)
power = 1/(1+exp(-(rnorm(1000, mean=w_sp, sd=5) -40)/5))

Предположим, мы хотим удалить power значения между [0,5), [5,10) и т.д.Тогда

bin_incr = 5
bins = seq(0, 95, bin_incr)
y_mean = sapply(bins, function(x) mean(power[w_sp >= x & w_sp < (x+bin_incr)]))

Теперь мы создали средние значения между интересующими нас диапазонами.Обратите внимание, что если вам нужны медианные значения, просто измените mean Для median.Все, что осталось сделать, это составить их план:

plot(w_sp, power)
points(seq(2.5, 97.5, 5), y_mean, col=3, pch=16)

Чтобы получить среднее значение на основе данных, которые находятся в пределах двух стандартных отклонений от среднего, нам нужно создать немного более сложную функцию:

noOutliers = function(x, power, w_sp, bin_incr) {
  d = power[w_sp >= x & w_sp < (x + bin_incr)]
  m_d = mean(d)
  d_trim = mean(d[d > (m_d - 2*sd(d)) & (d < m_d + 2*sd(d))])
  return(mean(d_trim))
}

y_no_outliers = sapply(bins, noOutliers, power, w_sp, bin_incr)

Вот несколько примеров подобранных кривых (анализ Вейбулла) для коммерческих турбин:

http://www.inl.gov/wind/software/

http://www.irec.cmerp.net/papers/WOE/Paper%20ID%20161.pdf

http://www.icaen.uiowa.edu /~ie_155/Лекция/Power_Curve.pdf

Я бы порекомендовал также поиграть с собственным ggplot2 Хэдли.Его веб-сайт - отличный ресурс: http://had.co.nz/ggplot2/ .

    # If you haven't already installed ggplot2:
    install.pacakges("ggplot2", dependencies = T)

    # Load the ggplot2 package
    require(ggplot2)

    # csgillespie's example data
    w_sp <- sample(seq(0, 100, 0.01), 1000)
    power <- 1/(1+exp(-(w_sp -40)/5)) + rnorm(1000, sd = 0.1)

    # Bind the two variables into a data frame, which ggplot prefers
    wind <- data.frame(w_sp = w_sp, power = power)

    # Take a look at how the first few rows look, just for fun
    head(wind)


    # Create a simple plot
    ggplot(data = wind, aes(x = w_sp, y = power)) + geom_point() + geom_smooth()

    # Create a slightly more complicated plot as an example of how to fine tune
    # plots in ggplot
    p1 <- ggplot(data = wind, aes(x = w_sp, y = power))
    p2 <- p1 + geom_point(colour = "darkblue", size = 1, shape = "dot") 
    p3 <- p2 + geom_smooth(method = "loess", se = TRUE, colour = "purple")
    p3 + scale_x_continuous(name = "mph") + 
             scale_y_continuous(name = "power") +
             opts(title = "Wind speed and power")
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top