2013-02-05 13 views
5

Ich habe eine Liste der Wetterstationen und ihrer Standorte nach Längen- und Breitengrad. Es gab Formatierungsprobleme und einige von ihnen haben Stunden und Minuten, während andere Stunden, Minuten und Sekunden haben. Ich kann das Muster mit Regex finden, aber ich habe Probleme beim Extrahieren der einzelnen Teile.R regex/gsub: Teil des Musters extrahieren

Hier Daten:

> head(wthrStat1) 
    Station  lat  lon 
1940 K01R 31-08N 092-34W 
1941 K01T 28-08N 094-24W 
1942 K03Y 48-47N 096-57W 
1943 K04V 38-05-50N 106-10-07W 
1944 K05F 31-25-16N 097-47-49W 
1945 K06D 48-53-04N 099-37-15W 

ich so etwas wie dies möchte:

Station  latHr latMin latSec latDir lonHr lonMin lonSec lonDir 
    1940 K01R 31 08  00  N  092 34  00  W 
    1941 K01T 28 08  00  N  094 24  00  W 
    1942 K03Y 48 47  00  N  096 57  00  W 
    1943 K04V 38 05  50  N  106 10  07  W 
    1944 K05F 31 25  16  N  097 47  49  W 
    1945 K06D 48 53  04  N  099 37  15  W 

Ich kann Spiele zu diesem Regex erhalten:

data.format <- "\\d{1,3}-\\d{1,3}(?:-\\d{1,3})?[NSWE]{1}" 
grep(data.format, wthrStat1$lat) 

aber bin nicht sicher, wie man die einzelnen Teile in Spalten. Ich habe ein paar Dinge ausprobiert wie:

wthrStat1$latHr <- ifelse(grepl(data.format, wthrStat1$lat), gsub(????), NA) 

aber ohne Glück.

Hier ist ein dput():

> dput(wthrStat1[1:10,]) 
structure(list(Station = c("K01R", "K01T", "K03Y", "K04V", "K05F", 
"K06D", "K07G", "K07S", "K08D", "K0B9"), lat = c("31-08N", "28-08N", 
"48-47N", "38-05-50N", "31-25-16N", "48-53-04N", "42-34-28N", 
"47-58-27N", "48-18-03N", "43-20N"), lon = c("092-34W", "094-24W", 
"096-57W", "106-10-07W", "097-47-49W", "099-37-15W", "084-48-41W", 
"117-25-42W", "102-24-23W", "070-24W")), .Names = c("Station", 
"lat", "lon"), row.names = 1940:1949, class = "data.frame") 

Irgendwelche Vorschläge?

+0

Haben Sie versucht * gruppieren * jede Spalte mit Pharentesis auf der Regex? –

+0

@OscarMederos: Nein, wie würdest du das tun? – screechOwl

+0

Ich weiß nicht, wie Regex in "R" funktioniert, aber in den meisten Sprachen können Sie Gruppen erstellen, indem Sie das einschließen, was Sie innerhalb der Pharentese benötigen. Wie 'id = (\ d +)'. Wenn Ihre Übereinstimmung 'ID = 1234' ist, ist die erste Gruppe '1234'. –

Antwort

6

es extrem ineffizient ist, ich hoffe, jemand anderes bessere Lösung hatte:

library(gsubfn) 
data.format <- "(\\d{1,3})-(\\d{1,3})-?(\\d{1,3})?([NSWE]{1})" 
parts <- strapplyc(wthrStat1$lat, data.format, simplify = rbind) 
parts[parts == ""] <- "00" 

die gibt:

dat <- read.table(text =' Station  lat  lon 
1940 K01R 31-08N 092-34W 
1941 K01T 28-08N 094-24W 
1942 K03Y 48-47N 096-57W 
1943 K04V 38-05-50N 106-10-07W 
1944 K05F 31-25-16N 097-47-49W 
1945 K06D 48-53-04N 099-37-15W', head=T) 


pattern <- '([0-9]+)[-]([0-9]+)([-|A-Z]+)([0-9]*)([A-Z]*)' 

dat$latHr <- gsub(pattern,'\\1',dat$lat) 
dat$latMin <- gsub(pattern,'\\2',dat$lat) 

latSec <- gsub(pattern,'\\4',dat$lat) 
latSec[nchar(latSec)==0] <- '00' 
dat$latSec <- latSec 

latDir <- gsub(pattern,'\\5',dat$lat) 
latDir[nchar(latDir)==0] <- latDir[nchar(latDir)!=0][1] 
dat$latDir <- latDir 

dat 
    Station  lat  lon latHr latMin latSec latDir 
1940 K01R 31-08N 092-34W 31  08  00  N 
1941 K01T 28-08N 094-24W 28  08  00  N 
1942 K03Y 48-47N 096-57W 48  47  00  N 
1943 K04V 38-05-50N 106-10-07W 38  05  50  N 
1944 K05F 31-25-16N 097-47-49W 31  25  16  N 
1945 K06D 48-53-04N 099-37-15W 48  53  04  N 
7

strapplyc im gsubfn Paket wird jede Gruppe in dem regulären Ausdruck mit Klammern umgeben extrahieren :

> parts 
     [,1] [,2] [,3] [,4] 
[1,] "31" "08" "00" "N" 
[2,] "28" "08" "00" "N" 
[3,] "48" "47" "00" "N" 
[4,] "38" "05" "50" "N" 
[5,] "31" "25" "16" "N" 
[6,] "48" "53" "04" "N" 
[7,] "42" "34" "28" "N" 
[8,] "47" "58" "27" "N" 
[9,] "48" "18" "03" "N" 
[10,] "43" "20" "00" "N" 
+0

Danke für das Hinweis auf die gsubfn-Paket. Ich mag die Art, wie es mit R passt, indem ich die * apply-Funktionen erweitere. Übrigens, für mich liefert strapplyc ein data.frame mit 1 Spalte von 6 Zeilen, die alle 'c' enthalten. strapply, während Teile <- strapply (df $ lat, Muster, FUN = c, simplify = rbind) wie erwartet funktionieren. (Version 0.6-5 von gsubfn auf R 2.15.1, fand es nicht tcltk). – cbare

+1

@cbare, Es ist ein Fehler. Es ist jetzt in der Subversion Repo fixiert. Um es zu benutzen: 'library (gsbufn); Quelle ("http://gsubfn.googlecode.com/svn/trunk/R/strapplyc.R") ". Außerdem finden Sie Informationen zur Installation von tcltk in den FAQs: https://code.google.com/p/gsubfn/#FAQs –

2

Eine andere Antwort,verwendend:

# example data 
data <- 
"Station  lat  lon 
1940 K01R 31-08N 092-34W 
1941 K01T 28-08N 094-24W 
1942 K03Y 48-47N 096-57W 
1943 K04V 38-05-50N 106-10-07W 
1944 K05F 31-25-16N 097-47-49W 
1945 K06D 48-53-04N 099-37-15W" 

## read string into a data.frame 
df <- read.table(text=data, head=T, stringsAsFactors=F) 

pattern <- "(\\d{1,3})-(\\d{1,3})(?:-(\\d{1,3}))?([NSWE]{1})" 

library(stringr) 
str_match(df$lat, pattern) 

dies einen data.frame mit einer Spalte für die gesamte Zeichenfolge passenden und eine zusätzliche Spalte für jede Einfang-Gruppe produziert.

 [,1]  [,2] [,3] [,4] [,5] 
[1,] "31-08N" "31" "08" "" "N" 
[2,] "28-08N" "28" "08" "" "N" 
[3,] "48-47N" "48" "47" "" "N" 
[4,] "38-05-50N" "38" "05" "-50" "N" 
[5,] "31-25-16N" "31" "25" "-16" "N" 
[6,] "48-53-04N" "48" "53" "-04" "N" 

R string processing Fähigkeit hat sich in den letzten Jahren Fortschritte gemacht.