Преобразование координат из степени с нетрадиционным форматом в десятичную степень - PullRequest
1 голос
/ 31 октября 2019

Я пытаюсь преобразовать свои данные, чтобы они могли отображаться на карте. Например, данные выглядят так:

# A tibble: 2 x 2
  Latitud           Longitud        
  <chr>             <chr>           
1 10º 35' 28.98'' N 3º 41' 33.91'' O
2 10º 35' 12.63'' N 3º 45' 46.22'' O

Я пытаюсь изменить их, используя следующее:

df %>% 
  mutate(
    Latitud = str_replace_all(Latitud, "''", ""),
    lat_edit = sp::char2dms(Latitud), "°")

Что возвращает и ошибка:

Error in if (any(abs(object@deg) > 90)) return("abs(degree) > 90") : 
  missing value where TRUE/FALSE needed
In addition: Warning message:
In asMethod(object) : NAs introduced by coercion

Iхотел бы нанести эти две точки на карту в ggplot (или другом пространственном пакете)

Данные:

structure(list(Latitud = c("40º 25' 25.98'' N", "40º 25' 17.63'' N"
), Longitud = c("3º 42' 43.91'' O", "3º 40' 56.22'' O")), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -2L))

Ответы [ 2 ]

3 голосов
/ 31 октября 2019

Вы можете использовать следующую пользовательскую функцию (я предполагаю, N, S, W, E. Не уверен, что O означает по долготе):

angle2dec <- function(angle) {
  angle <- as.character(angle)
  angle <- ifelse(grepl("S|W", angle), paste0("-", angle), angle)
  angle <- trimws(gsub("[^- +.0-9]", "", angle))
  x <- do.call(rbind, strsplit(angle, split=' '))
  x <- apply(x, 1L, function(y) {
    y <- as.numeric(y)
    (abs(y[1]) + y[2]/60 + y[3]/3600) * sign(y[1])
  })
  return(x)
}

Применение по данным:

df1[] <- lapply(df1, angle2dec)

df1
#>     Latitud  Longitud
#> 1 -40.42388  3.712197
#> 2  40.42156 -3.682283

Печать:

library(ggplot2)

ggplot(df1, aes(x = Longitud, y = Latitud)) +
  geom_point()


Слегка измененные данные для отображения для разных полушарий:

df1 <- structure(list(Latitud = c("40<U+623C><U+3E61> 25' 25.98'' S", 
                                  "40<U+623C><U+3E61> 25' 17.63'' N"), 
                      Longitud = c("3<U+623C><U+3E61> 42' 43.91'' E",
                                   "3<U+623C><U+3E61> 40' 56.22'' W")), 
                 class = c("tbl_df", "tbl", "data.frame"), 
                 row.names = c(NA, -2L))

Применительно к Преобразование географических координат из градуса вдесятичное число .

2 голосов
/ 31 октября 2019

Я предвосхищу это, сказав, что я не использовал char2dms до сих пор, так что могут быть сложности, которые я пропустил (например, мой вопрос выше о "O" как направление). Глядя на документы и примеры, вам нужно указать символы, используемые для разграничения градусов, минут и секунд. В вашем случае это "º", "'" и "''" соответственно. Я пропустил шаг удаления третьего из них, потому что необходимо увидеть, где пишутся секунды. ( Обновление: добавлен шаг для замены регулярного выражения "O$" (oeste) на "W" (запад)). Это дает вам то, что ниже:

library(dplyr)
library(ggplot2)
library(sp)

dat <- structure(list(Latitud = c("40º 25' 25.98'' N", "40º 25' 17.63'' N"
), Longitud = c("3º 42' 43.91'' O", "3º 40' 56.22'' O")), class = c("tbl_df", 
                                                                    "tbl", "data.frame"), row.names = c(NA, -2L)) %>%
  mutate_at(vars(Latitud, Longitud), stringr::str_replace_all, "O$", "W")

char2dms(dat$Latitud, chd = "º", chm = "'", chs = "''")
#> [1] 40d25'25.98"N 40d25'17.63"N

Это DMS S3 объект, а не вектор (на этом мои знания заканчиваются), поэтому вы не можете поместить его непосредственно в столбцы фрейма данных,Вместо этого преобразуйте в числовой вектор, и вы получите числовые координаты во фрейме данных.

dat_numeric <- dat %>%
  mutate(lat_edit = as.numeric(char2dms(dat$Latitud, chd = "º", chm = "'", chs = "''")),
         lon_edit = as.numeric(char2dms(dat$Longitud, chd = "º", chm = "'", chs = "''")))

dat_numeric
#> # A tibble: 2 x 4
#>   Latitud           Longitud         lat_edit lon_edit
#>   <chr>             <chr>               <dbl>    <dbl>
#> 1 40º 25' 25.98'' N 3º 42' 43.91'' W     40.4    -3.71
#> 2 40º 25' 17.63'' N 3º 40' 56.22'' W     40.4    -3.68

Постройте как обычные числа:

ggplot(dat_numeric, aes(x = lon_edit, y = lat_edit)) +
  geom_point()

Или преобразовать в sf объект и график с соответствующим соотношением сторон, проекцией и т. Д.

sf::st_as_sf(dat_numeric, coords = c("lon_edit", "lat_edit")) %>%
  ggplot() +
  geom_sf()

enter image description here

...