J'utilise R pour filtrer les traces de cyclones tropicaux passant sur une grille. J'ai un fichier csv contenant les pistes et je les convertis en fichier de formes.

Je voulais filtrer uniquement les points avec le même identifiant (la colonne "SN" dans les exemples de données ci-dessous) qui passaient sur une zone de grille spécifiée (5N à 25N et 115E à 135 E). Vous trouverez ci-dessous le code que j'utilise et le lien vers les données.

jtwc   <- read.csv("1979-1993_TC.csv",header=T,sep=",")

latmin <-5.00
latmax <- 25.00
lonmin <- 115.00
lonmax <- 135.00

jtwc.unique <- unique(jtwc[jtwc$Lat >= latmin & jtwc$Lat <= latmax & jtwc$Lon >= lonmin & jtwc$Lon <= lonmax,c(1,2)])
jtwc.filter <- merge(jtwc,jtwc.unique,all.x = F,all.y = T, sort = F)
jtwc.filter$Lon <- ifelse(jtwc.filter$Lon < 0, jtwc.filter$Lon + 360, jtwc.filter$Lon)
jtwc.filter <- jtwc.filter[with(jtwc.filter,order(Year,Month,Day,Hour,CY)),]

write.table(jtwc.filter,file = "test2_jul_par_1979-1993.csv", sep = ",", row.names = F)

Problème:

Ce code ne fonctionne pas correctement. Quand j'ai exécuté le script, je vois toujours des pistes en dehors de la boîte.

Quelqu'un peut-il suggérer un moyen d'améliorer cela?

J'apprécierai toute aide.

1
Lyndz 20 avril 2017 à 03:19

3 réponses

Meilleure réponse

Voici une approche qui utilise data.table pour faire la manipulation des données, puis utilise googleway pour tracer les traces sur Google Maps

library(googleway)
library(data.table) ## because I like working with data.table to do data manipulation

jtwc <- read.csv("~/Downloads/1979-1993_TC.csv")
setDT(jtwc)  ## set as data.table

latmin <-5.00
latmax <- 25.00
lonmin <- 115.00
lonmax <- 135.00

df_bounds <- data.frame(north = latmax, south = latmin, west = lonmin, east = lonmax)

## apply a logical column whether the point is in the box
jtwc[, inBounds := Lat >= latmin & Lat <= latmax & Lon >= lonmin & Lon <= lonmax]


## create a column that identifies if the SN at some point passes through the box
jtwc[SN %in% jtwc[inBounds == TRUE, unique(SN)], passesThroughBox := T ]
jtwc[is.na(passesThroughBox), passesThroughBox := F]

## adding a colour for plotting
jtwc[, colour := ifelse(passesThroughBox, "#4286F4", "#F44141") ]

## you need a google maps API key to plot on Google Maps
map_key <- 'your_api_key'

google_map(key = map_key) %>%
    add_polylines(data = jtwc, lat = "Lat", lon = "Lon", id = "SN", stroke_colour = 'colour',
                                mouse_over_group = 'passesThroughBox') %>%
    add_rectangles(data = df_bounds, north = 'north', south = 'south', west = 'west', east = 'east',
                                 fill_opacity = 0.1)

enter image description here

Ensuite, en survolant les lignes, vous pouvez voir celles qui passent à travers

enter image description here

2
SymbolixAU 28 mai 2017 à 21:44

Pour filtrer, vous pouvez utiliser

library(dplyr)

dat %>% 
    filter(Lat>=5 & Lat <=25 & Lon>=115 & Lon<135)

Inversement, si vous souhaitez conserver le bloc de données d'origine, vous pouvez utiliser

    dat %>% 
        mutate(boxed = ifelse(Lat>=5 & Lat <=25 & Lon>=115 & Lon<135, 1,0))

Si vous souhaitez tracer les pistes

library(ggplot2)

dat %>% 
    mutate(boxed = ifelse(Lat>=5 & Lat <=25 & Lon>=115 & Lon<135, 1,0)) %>% 
    ggplot(aes(Lon,Lat, color=factor(boxed)))+geom_point()
3
B Williams 20 avril 2017 à 01:28

Ce code corrige le problème de base, mais je ne sais pas s'il résout complètement votre problème. Votre code d'origine semble supposer que la combinaison de CY et de SN est unique dans l'ensemble de données, ce qui, à mon avis, est faux. Il doit y avoir des combinaisons avec des mesures différentes pour la même paire. Cette version enregistre les valeurs bounded puis fusionne avec cette table bounded

library(assertthat)

jtwc   <- read.csv("~/Downloads/1979-1993_TC.csv", header=T, sep=",")

latmin <-5.00
latmax <- 25.00
lonmin <- 115.00
lonmax <- 135.00

# adjust for negative lat
jtwc$Lon <- ifelse(jtwc$Lon < 0, jtwc$Lon + 360, jtwc$Lon)

# derive the bounded points 
jtwc.bounded <- jtwc[jtwc$Lat >= latmin & jtwc$Lat <= latmax & jtwc$Lon >= lonmin & jtwc$Lon <= lonmax,]

# all these are TRUE
assert_that (all(jtwc.bounded$Lat >= latmin))
assert_that (all(jtwc.bounded$Lat <= latmax))
assert_that (all(jtwc.bounded$Lon >= lonmin))
assert_that (all(jtwc.bounded$Lon <= lonmax))


jtwc.unique <- unique(jtwc.bounded[,c(1,2)])

# merge with bounded (
jtwc.filter <- merge(jtwc.bounded, jtwc.unique, all.x = F, all.y = T, sort = F)

assert_that (all(jtwc.filter$Lat >= latmin))
assert_that (all(jtwc.filter$Lat <= latmax))
assert_that (all(jtwc.filter$Lon >= lonmin))
assert_that (all(jtwc.filter$Lon <= lonmax))


jtwc.filter <- jtwc.filter[with(jtwc.filter,order(Year,Month,Day,Hour,CY)),]

write.table(jtwc.filter,file = "test2_jul_par_1979-1993.csv", sep = ",", row.names = F)
2
Andrew Lavers 20 avril 2017 à 01:36