2017-02-09 10 views
2

J'essaie de convertir des données de vent de format long en format large. La vitesse du vent et la direction du vent sont répertoriées dans la colonne Parameter.Name. Ces valeurs doivent être castées par les variables Local.Site.Name et Date.Local.Remodelage des données de vitesse et de direction du vent EPA avec dcast dans R

S'il y a plusieurs observations par ligne Local.Site.Name + Date.Local unique, alors je veux la valeur moyenne de ces observations. L'argument intégré 'fun.aggregate = mean' fonctionne très bien pour la vitesse du vent, mais la direction moyenne du vent ne peut pas être calculée de cette façon car les valeurs sont en degrés. Par exemple, la moyenne de deux directions du vent près du Nord (350, 10) produirait comme Sud (180). Par exemple: ((350 + 10)/2 = 180), malgré la moyenne polaire de 360 ​​ou 0.

Le paquet 'circulaire' nous permettra de calculer la direction moyenne du vent sans avoir à effectuer de trigonométrie, mais J'ai du mal à essayer d'imbriquer cette fonction supplémentaire dans l'argument 'fun.agrgregate'. Je pensais que d'une simple instruction else if ferait l'affaire, mais je suis en cours d'exécution dans l'erreur suivante:

Error in vaggregate(.value = value, .group = overall, .fun = fun.aggregate, : could not find function ".fun" 
In addition: Warning messages: 
1: In if (wind$Parameter.Name == "Wind Direction - Resultant") { : 
    the condition has length > 1 and only the first element will be used 
2: In if (wind$Parameter.Name == "Wind Speed - Resultant") { : 
    the condition has length > 1 and only the first element will be used  
3: In mean.default(wind$"Wind Speed - Resultant") : 
    argument is not numeric or logical: returning NA 

L'objectif est d'être en mesure d'utiliser le fun.aggregate = mean pour Vitesse du vent, mais le mean(circular(Wind Direction, units = 'degrees') la direction du vent.

est ici les données originales (> 100 Mo): https://drive.google.com/open?id=0By6o_bZ8CGwuUUhGdk9ONTgtT0E

est ici un sous-ensemble des données (1er 100 lignes): https://drive.google.com/open?id=0By6o_bZ8CGwucVZGT0pBQlFzT2M

Voici mon script:

library(reshape2) 
library(dplyr) 
library(circular) 

#read in the long format data: 
wind <- read.csv("<INSERT_FILE_PATH_HERE>", header = TRUE) 

#cast into wide format: 
wind.w <- dcast(wind, 
      Local.Site.Name + Date.Local ~ Parameter.Name, 
      value.var = "Arithmetic.Mean", 
      fun.aggregate = (
       if (wind$Parameter.Name == "Wind Direction - Resultant") { 
       mean(circular(wind$"Wind Direction - Resultant", units = 'degrees')) 
       } 
       else if (wind$Parameter.Name == "Wind Speed - Resultant") { 
       mean(wind$"Wind Speed - Resultant") 
       }), 
      na.rm = TRUE) 

Toute aide serait grandement apprécié!

-spacedSparking

EDIT: VOICI LA SOLUTION:

library(reshape2) 
library(SDMTools) 
library(dplyr) 
#read in the EPA wind data: 
#This data is publicly accessible, and can be found here: https://aqsdr1.epa.gov/aqsweb/aqstmp/airdata/download_files.html  
wind <- read.csv("daily_WIND_2016.csv", sep = ',', header = TRUE, stringsAsFactors = FALSE) 

#convert long format wind speed data by date and site id: 
wind_speed <- dcast(wind, 
        Local.Site.Name + Date.Local ~ Parameter.Name, 
        value.var = "Arithmetic.Mean", 
        fun.aggregate = function(x) { 
         mean(x, na.rm=TRUE) 
        }, 
        subset = .(Parameter.Name == "Wind Speed - Resultant") 
) 

#convert long format wind direction data into wide format by date and local site id: 
wind_direction <- dcast(wind, 
         Local.Site.Name + Date.Local ~ Parameter.Name, 
         value.var = "Arithmetic.Mean", 
         fun.aggregate = function(x) { 
          if(length(x) > 0) 
          circular.averaging(x, deg = TRUE) 
          else 
          -1 
         }, 
         subset= .(Parameter.Name == "Wind Direction - Resultant") 
) 

#join the wide format split wind_speed and wind_direction dataframes 
wind.w <- merge(wind_speed, wind_direction) 
+0

Vous devez découper le haut de votre fichier de données sur les 100 premières lignes environ et l'afficher ici.Faire en sorte que tout le monde qui veut répondre à votre question télécharger 106 Mo est susceptible de réduire le nombre d'aides. – Richard

+0

Je me suis assuré de réduire les données à 100 lignes. Merci pour la suggestion que je suis nouveau à empiler! – spacedSparking

+0

Merci, c'est beaucoup plus facile de travailler avec, mais avez-vous vérifié que ce petit jeu de données montre toujours le problème que vous essayez de résoudre? Votre objectif sur SO est de rendre aussi accessible que possible les ressources disponibles pour comprendre et répondre à votre question. – Richard

Répondre

0

vous pouvez utiliser sous-ensemble dans dcast pour appliquer les deux fonctions et obtenir séparés dataframes les fusionner puis

library(reshape2) 
library(dplyr) 
library(circular) 

#cast into wide format: 
wind_speed <- dcast(wind, 
       Local.Site.Name + Date.Local ~ Parameter.Name, 
       value.var = "Arithmetic.Mean", 
       fun.aggregate = function(x) { 
        mean(x, na.rm=TRUE) 
       }, 
       subset=.(Parameter.Name == "Wind Speed - Resultant") 
) 

wind_direction <- dcast(wind, 
        Local.Site.Name + Date.Local ~ Parameter.Name, 
        value.var = "Arithmetic.Mean", 
        fun.aggregate = function(x) { 
         if(length(x) > 0) 
         mean(circular(c(x), units="degrees"), na.rm=TRUE) 
         else 
         -1 
        }, 
        subset=.(Parameter.Name == "Wind Direction - Resultant") 
) 


wind.w <- merge(wind_speed, wind_direction) 
+0

Ceci est Cela étant dit, je me suis rendu compte que la fonction 'circular()' n'agrège pas la direction du vent de la façon dont je l'espérais.Enfin, je veux ma direction moyenne du vent par Le site et la date doivent être dans la même gamme de 0 et 360 degrés J'espère utiliser certaines fonctions du paquet 'openair' dans l'espoir de résoudre ce problème à la place.J'apprécie votre réponse! – spacedSparking

0

Vous utilisez wind.w à l'intérieur du code qui définit wind.w - qui ne va pas au travail!

Vous utilisez également les guillemets inclinés (`) au lieu des guillemets droits ('). Les guillemets droits doivent être utilisés pour délimiter une chaîne.

+0

Merci d'avoir signalé le problème 'wind.w'. La saisie semi-automatique me pose des problèmes avec des marques de citation inclinées, merci. Après avoir fait ces changements, je me retrouve avec l'erreur suivante: – spacedSparking

+0

'Erreur dans l'agrégat (.value = valeur, .group = global, .fun = fun.aggregate,: n'a pas pu trouver la fonction" .fun "' – spacedSparking

0

bien merci à tous de votre aide, je réussi à résoudre ce problème agaçant de direction du vent. Parfois, la résolution de problèmes consiste simplement à connaître les bonnes questions à poser. Dans mon cas, apprendre le terme «vectorisation moyenne» était tout ce dont j'avais besoin! Il y a une fonction intégrée de moyenne de vecteur appelée circular.averaging() du paquet SDMTools qui fait la moyenne de la direction du vent et produit une sortie qui est toujours entre 0-359 degrés! Ce que j'ai fini par faire était d'ajouter le script de tjjjohnson. J'ai changé l'argument fun.aggregate de mean(circular(c(x), units = "degrees"), na.rm = TRUE) à circular.averaging(x, deg = TRUE) Voici les histogrammes des données raw and aggregated! Tout a l'air bien, merci à tous!