Chuyển đổi dữ liệu chuỗi thành khung dữ liệu


8

Tôi mới sử dụng R, mọi đề xuất sẽ được đánh giá cao.

Đây là dữ liệu:

coordinates <- "(-79.43591570873059, 43.68015339477487), (-79.43491506339724, 43.68036886994886), (-79.43394727223847, 43.680578504490335), (-79.43388162422195, 43.68058996121469), (-79.43281544978878, 43.680808044458765), (-79.4326971769691, 43.68079658822322)"

Tôi muốn điều này trở thành:

Latitude           Longitude
-79.43591570873059 43.68015339477487
-79.43491506339724 43.68036886994886
-79.43394727223847 43.680578504490335
-79.43388162422195 43.68058996121469
-79.43281544978878 43.680808044458765
-79.4326971769691  43.68079658822322

Câu trả lời:


3

Chúng ta có thể sử dụng str_extract_alltừstringr

library(stringr)

df <- data.frame(Latitude = str_extract_all(coordinates, "(?<=\\()-\\d+\\.\\d+")[[1]], 
      Longitude = str_extract_all(coordinates, "(?<=,\\s)\\d+\\.\\d+(?=\\))")[[1]])
df
#            Latitude          Longitude
#1 -79.43591570873059  43.68015339477487
#2 -79.43491506339724  43.68036886994886
#3 -79.43394727223847 43.680578504490335
#4 -79.43388162422195  43.68058996121469
#5 -79.43281544978878 43.680808044458765
#6  -79.4326971769691  43.68079658822322

Latitudechụp số thập phân âm từ mở dấu ngoặc tròn ( () trong khi Longitudechụp nó từ dấu phẩy ( ,) đến dấu ngoặc tròn ( )).

Hoặc không có regex nhìn và phía sau và chụp lại với nhau bằng cách sử dụng str_match_all

df <- data.frame(str_match_all(coordinates, 
                        "\\((-\\d+\\.\\d+),\\s(\\d+\\.\\d+)\\)")[[1]][, c(2, 3)])

Để chuyển đổi dữ liệu thành các loại tương ứng, bạn có thể sử dụng type.convert

df <- type.convert(df)

Điều này tạo ra LatitudeLongitudenhư là các yếu tố có thể gây ra khó khăn.
dcarlson

@dcarlson Cập nhật câu trả lời cho điều đó.
Ronak Shah

4

Bạn có thể sử dụng scanvới một chút gsub:

matrix(scan(text = gsub("[()]", "", coordinates), sep = ","), 
       ncol = 2, byrow = TRUE, dimnames = list(NULL, c("Lat", "Long")))
# Read 12 items
#            Lat     Long
# [1,] -79.43592 43.68015
# [2,] -79.43492 43.68037
# [3,] -79.43395 43.68058
# [4,] -79.43388 43.68059
# [5,] -79.43282 43.68081
# [6,] -79.43270 43.68080

Độ chính xác vẫn còn đó - chỉ bị cắt bớt trong màn hình ma trận.

Hai lợi thế rõ ràng:

  • Nhanh.
  • Xử lý vectơ "tọa độ" đa phần tử (ví dụ: coordinates <- rep(coordinates, 10)làm đầu vào).

Đây là một lựa chọn khác:

library(data.table)
fread(gsub("[()]", "", gsub("), (", "\n", toString(coordinates), fixed = TRUE)), header = FALSE)

Các toString(coordinates)trường hợp là khi length(coordinates) > 1. Bạn cũng có thể sử dụng fread(text = gsub(...), ...)và bỏ qua sử dụng toString. Tôi không chắc chắn về những lợi thế hoặc hạn chế của một trong hai cách tiếp cận.


2

Đây là một tùy chọn cơ sở R:

coordinates <- "(-79.43591570873059, 43.68015339477487), (-79.43491506339724, 43.68036886994886), (-79.43394727223847, 43.680578504490335), (-79.43388162422195, 43.68058996121469), (-79.43281544978878, 43.680808044458765), (-79.4326971769691, 43.68079658822322)"
coordinates <- gsub("^\\(|\\)$", "", coordinates)
x <- strsplit(coordinates, "\\), \\(")[[1]]
df <- data.frame(lat=sub(",.*$", "", x), lng=sub("^.*, ", "", x), stringsAsFactors=FALSE)
df

Chiến lược ở đây là trước tiên loại bỏ các dấu ngoặc đơn hàng đầu, sau đó tách chuỗi \), \(để tạo ra một vectơ ký tự duy nhất với mỗi cặp vĩ độ / kinh độ. Cuối cùng, chúng tôi tạo ra một đầu ra khung dữ liệu.

                 lat                lng
1 -79.43591570873059  43.68015339477487
2 -79.43491506339724  43.68036886994886
3 -79.43394727223847 43.680578504490335
4 -79.43388162422195  43.68058996121469
5 -79.43281544978878 43.680808044458765
6  -79.4326971769691 43.68079658822322

Điều này tạo ra latlngnhư là các yếu tố có thể gây ra khó khăn.
dcarlson

1
@dcarlson Sau đó sử dụng stringsAsFactors=FALSEkhi tạo khung dữ liệu.
Tim Biegeleisen

2

Một phiên bản R cơ sở khác với một chút regex, dựa trên thực tế là thay thế dấu câu bằng các dòng trống sẽ có nghĩa là chúng bị bỏ qua khi nhập.

read.csv(text=gsub(")|(, |^)\\(", "\n", coordinates), col.names=c("lat","long"), header=FALSE)
#        lat     long
#1 -79.43592 43.68015
#2 -79.43492 43.68037
#3 -79.43395 43.68058
#4 -79.43388 43.68059
#5 -79.43282 43.68081
#6 -79.43270 43.68080

Ưu điểm:

  • Thỏa thuận với đầu vào vector cũng như scancâu trả lời khác .
  • Chuyển đổi thành các kiểu số chính xác trong đầu ra

Nhược điểm:

  • Không siêu nhanh

2

Chúng ta có thể sử dụng rm_roundtừqdapRegex

library(qdapRegex)
read.csv(text = rm_round(coordinates, extract = TRUE)[[1]], header = FALSE,
      col.names = c('lat', 'lng'))
#    lat      lng
#1 -79.43592 43.68015
#2 -79.43492 43.68037
#3 -79.43395 43.68058
#4 -79.43388 43.68059
#5 -79.43282 43.68081
#6 -79.43270 43.68080

Hoặc kết hợp với tidyverse

library(tidyr)
library(dplyr)
rm_round(coordinates, extract = TRUE)[[1]] %>%
     tibble(col1 = .) %>%
     separate(col1, into = c('lat', 'lng'), sep= ",\\s*", convert = TRUE)
# A tibble: 6 x 2
#    lat   lng
#  <dbl> <dbl>
#1 -79.4  43.7
#2 -79.4  43.7
#3 -79.4  43.7
#4 -79.4  43.7
#5 -79.4  43.7
#6 -79.4  43.7
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.