R Language - Tri des données en intervalles; la moyenne; ne pas tenir compte des valeurs aberrantes
Question
J'analyse des données d'une éolienne, normalement c'est le genre de chose que je ferais dans Excel, mais la quantité de données nécessite lourds de quelque chose. Je ne l'ai jamais utilisé R avant et donc je suis à la recherche de quelques conseils.
Les données se compose de 2 colonnes WINDSPEED et Power , jusqu'à présent je suis arrivé à l'importation des données à partir d'un fichier CSV et scatter-tracé les deux uns contre les autres.
Ce que je voudrais faire ensuite est de trier les données dans les gammes; par exemple toutes les données où Windspeed est compris entre x et y et ensuite trouver la moyenne de la puissance générée pour chaque plage et représenter graphiquement la courbe formée.
A partir de cette moyenne, je veux recalcule la moyenne à partir des données qui se situe dans l'une des deux écarts-types de la moyenne (essentiellement des valeurs aberrantes) en ignorant.
Les pointeurs sont appréciés.
Pour ceux qui sont intéressés, je suis en train de créer un graphique similaire à ce . Son un joli type de graphique standard, mais comme je l'ai dit la quantité de cisaillement de données nécessite quelque chose de plus lourd que Excel.
La solution
Jeter cette version, similaire dans la motivation que @ hadley de, dans le mélange à l'aide d'un modèle additif avec un plus lisse adaptatif en utilisant mgcv
paquet:
données fictives premier, tel qu'il est utilisé par @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)
ajuster le modèle additif en utilisant gam()
, en utilisant une plus lisse adaptatif et la sélection de lissage via MVR
require(mgcv)
mod <- gam(power ~ s(w_sp, bs = "ad", k = 20), data = df, method = "REML")
summary(mod)
Prédire de notre modèle et obtenir des erreurs standards d'ajustement, utiliser celui-ci pour générer un intervalle approximatif confiance de 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)
tout terrain et l'ajustement pour la comparaison Loess
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)
Autres conseils
Puisque vous n'êtes plus dans Excel, pourquoi ne pas utiliser une méthode statistique moderne qui ne nécessite pas binning brut des données et des méthodes ad hoc pour éliminer les valeurs aberrantes. Localement lisse régression, mis en œuvre par loess
En utilisant une légère modification des données d'échantillons 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)
Nous allons d'abord créer des exemples de données pour rendre le béton problème:
w_sp = sample(seq(0, 100, 0.01), 1000)
power = 1/(1+exp(-(rnorm(1000, mean=w_sp, sd=5) -40)/5))
Supposons que nous voulons bin les valeurs power
entre [0,5), [5,10), etc. Ensuite,
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)]))
Nous avons créé les valeurs moyennes entre les gammes d'intérêt. Notez que si vous vouliez les valeurs médianes, il suffit de changer mean
à median
. Tout ce qui reste à faire est de les tracer:
plot(w_sp, power)
points(seq(2.5, 97.5, 5), y_mean, col=3, pch=16)
Pour obtenir la moyenne en fonction des données comprises dans deux écarts-types de la moyenne, nous avons besoin de créer une fonction un peu plus compliqué:
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)
Voici quelques exemples de courbes ajustées (analyse Weibull) pour turbines commerciales:
http://www.inl.gov/wind/software/
http://www.irec.cmerp.net/ papiers / MALHEUR / papier% 20ID% 20161.pdf
http://www.icaen.uiowa.edu/~ie_155/ conférence / Power_Curve.pdf
Je vous recommande également de jouer avec propre ggplot2 de Hadley. Son site est une excellente ressource. 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")