Lenguaje R: clasificación de datos en rangos;promediando;ignorar los valores atípicos

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

  •  27-10-2019
  •  | 
  •  

Pregunta

Estoy analizando datos de una turbina eólica; normalmente este es el tipo de cosas que haría en Excel, pero la cantidad de datos requiere algo pesado.Nunca he usado R antes, por lo que solo estoy buscando algunos consejos.

Los datos constan de 2 columnas. Velocidad del viento y Fuerza, hasta ahora he llegado a importar los datos de un archivo CSV y he trazado los dos entre sí.

Lo que me gustaría hacer a continuación es ordenar los datos en rangos;por ejemplo todos los datos donde Velocidad del viento está entre x e y y luego encuentre el promedio de potencia generada para cada rango y represente gráficamente la curva formada.

A partir de este promedio, quiero volver a calcular el promedio en función de los datos que se encuentran dentro de una de las dos desviaciones estándar del promedio (básicamente ignorando los valores atípicos).

Se agradece cualquier sugerencia.

Para aquellos que estén interesados, estoy intentando crear un gráfico similar a este.Es un tipo de gráfico bastante estándar, pero como dije, la gran cantidad de datos requiere algo más pesado que Excel.

¿Fue útil?

Solución

Agregue esta versión, similar en motivación a la de @ hadley, en la mezcla usando un modelo aditivo con un suavizador adaptativo usando el paquete mgcv:

Primero, datos ficticios, como los usa @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)

Ajuste el modelo aditivo usando gam(), usando una selección de suavidad y suavidad adaptativa a través de REML

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

Predecir a partir de nuestro modelo y obtener errores estándar de ajuste, utilice este último para generar un intervalo de confianza aproximado del 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)

Trace todo y el Loess se ajusta a la comparación

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)

adaptabilidad suave y encajables

Otros consejos

Dado que ya no está en Excel, ¿por qué no utilizar una metodología estadística moderna que no requiera un agrupamiento burdo de los datos y métodos ad hoc para eliminar valores atípicos: regresión localmente suave, tal como lo implementó loess?

Usando una ligera modificación de los datos de muestra de 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)

Primero crearemos algunos datos de ejemplo para concretar el problema:

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

Supongamos que queremos descartar el power valores entre [0,5), [5,10), etc.Entonces

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)]))

Ahora hemos creado los valores medios entre los rangos de interés.Tenga en cuenta que si desea los valores medianos, simplemente cambie mean a median.Todo lo que queda por hacer es trazarlos:

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

Para obtener el promedio basado en datos que se encuentran dentro de dos desviaciones estándar del promedio, necesitamos crear una función un poco más complicada:

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)

A continuación, se muestran algunos ejemplos de curvas ajustadas (análisis Weibull) para turbinas comerciales:

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

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

http://www.icaen.uiowa.edu/~ie_155/Lecture / Power_Curve.pdf

Recomiendo también jugar con el propio ggplot2 de Hadley.Su sitio web es un gran recurso: 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")
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top