2013-02-05 41 views
5

Tôi có danh sách các trạm thời tiết và vị trí của chúng theo vĩ độ và kinh độ. Đã xảy ra sự cố định dạng và một số trong số đó có giờ và phút trong khi một số khác có giờ, phút và giây. Tôi có thể tìm thấy các mô hình bằng cách sử dụng regex nhưng tôi đang gặp rắc rối giải nén các mảnh riêng lẻ.R regex/gsub: trích xuất một phần của mẫu

Dưới đây là dữ liệu:

> 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 

Tôi muốn một cái gì đó như thế này:

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 

tôi có thể nhận được các trận đấu để regex này:

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

Nhưng không chắc chắn làm thế nào để có được các phần riêng lẻ thành các cột. Tôi đã thử một vài điều như:

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

nhưng không có may mắn.

Dưới đây là một 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") 

Bất kỳ lời đề nghị?

+0

Bạn đã thử * nhóm * mỗi cột bằng cách sử dụng pharentesis trên regex? –

+0

@OscarMederos: Không, bạn sẽ làm như thế nào? – screechOwl

+0

Tôi không biết làm thế nào regex làm việc trong 'R', nhưng trong hầu hết các ngôn ngữ bạn có thể tạo các nhóm bằng cách bao gồm những gì bạn cần bên trong pharentesis. Giống như 'id = (\ d +)'. Nếu trận đấu của bạn là 'id = 1234 ', nhóm thứ nhất sẽ là' 1234'. –

Trả lời

6

nó là vô cùng hiệu quả, tôi hy vọng ai đó có giải pháp tốt hơn:

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 trong gói gsubfn sẽ trích xuất từng nhóm trong biểu thức chính quy bao quanh với ngoặc:

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" 

mang đến cho :

> 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

Cảm ơn bạn đã chỉ ra gói gsubfn. Tôi thích cách nó phù hợp với R bằng cách mở rộng các chức năng * áp dụng. BTW, đối với tôi, strapplyc trả về một data.frame với 1 cột gồm 6 hàng chứa tất cả 'c'. strapply, trong khi các phần <- strapply (df $ lat, pattern, FUN = c, simplify = rbind) hoạt động như mong đợi. (phiên bản 0.6-5 của gsubfn trên R 2.15.1, nó không tìm thấy tcltk). – cbare

+1

@cbare, Lỗi của nó. Bây giờ nó đã được sửa trong repo subversion. Để sử dụng nó: 'library (gsbufn); nguồn ("http://gsubfn.googlecode.com/svn/trunk/R/strapplyc.R") '. Ngoài ra còn có thông tin về cài đặt tcltk trong Câu hỏi thường gặp: https://code.google.com/p/gsubfn/#FAQs –

2

Câu trả lời khác, sử dụng stringr:

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

Điều này tạo ra data.frame với một cột cho toàn bộ chuỗi phù hợp và cột bổ sung cho mỗi nhóm chụp.

 [,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" 

Khả năng của R đã đạt được rất nhiều trong vài năm qua.

Các vấn đề liên quan