Преобразование геокоординат от степени к десятичной

Я хочу преобразовать свои географические координаты из gradleусов в десятичные числа, мои данные таковы:

lat long 105252 30°25.264 9°01.331 105253 30°39.237 8°10.811 105255 31°37.760 8°06.040 105258 31°41.190 8°06.557 105259 31°41.229 8°06.622 105260 31°38.891 8°06.281 

У меня есть этот код, но я не понимаю, почему он не работает:

 convert<-function(coord){ tmp1=strsplit(coord,"°") tmp2=strsplit(tmp1[[1]][2],"\\.") dec=c(as.numeric(tmp1[[1]][1]),as.numeric(tmp2[[1]])) return(dec[1]+dec[2]/60+dec[3]/3600) } don_convert=don1 for(i in 1:nrow(don1)){don_convert[i,2]=convert(as.character(don1[i,2])); don_convert[i,3]=convert(as.character(don1[i,3]))} . convert<-function(coord){ tmp1=strsplit(coord,"°") tmp2=strsplit(tmp1[[1]][2],"\\.") dec=c(as.numeric(tmp1[[1]][1]),as.numeric(tmp2[[1]])) return(dec[1]+dec[2]/60+dec[3]/3600) } don_convert=don1 for(i in 1:nrow(don1)){don_convert[i,2]=convert(as.character(don1[i,2])); don_convert[i,3]=convert(as.character(don1[i,3]))} 

Функция конвертации работает, но код, в котором я прошу цикл выполнить эту работу, не работает.

Любое предложение является apperciated.

Используйте пакет measurements из CRAN, у которого уже есть функция преобразования единиц, поэтому вам не нужно создавать свои собственные:

 x = read.table(text = " lat long 105252 30°25.264 9°01.331 105253 30°39.237 8°10.811 105255 31°37.760 8°06.040 105258 31°41.190 8°06.557 105259 31°41.229 8°06.622 105260 31°38.891 8°06.281", header = TRUE, stringsAsFactors = FALSE) 

Как только ваш data.frame настроен, тогда:

 # change the degree symbol to a space x$lat = gsub('°', ' ', x$lat) x$long = gsub('°', ' ', x$long) # convert from decimal minutes to decimal degrees x$lat = measurements::conv_unit(x$lat, from = 'deg_dec_min', to = 'dec_deg') x$long = measurements::conv_unit(x$long, from = 'deg_dec_min', to = 'dec_deg') 

Результат в конечном продукте:

  lat long 105252 30.4210666666667 9.02218333333333 105253 30.65395 8.18018333333333 105255 31.6293333333333 8.10066666666667 105258 31.6865 8.10928333333333 105259 31.68715 8.11036666666667 105260 31.6481833333333 8.10468333333333 

Попробуйте использовать функцию char2dms в библиотеке sp . Он имеет другие функции, которые дополнительно будут делать десятичное преобразование.

 library("sp") ?char2dms 

Немного векторизации и манипуляции с matrixми сделает вашу функцию намного проще:

 x <- read.table(text=" lat long 105252 30°25.264 9°01.331 105253 30°39.237 8°10.811 105255 31°37.760 8°06.040 105258 31°41.190 8°06.557 105259 31°41.229 8°06.622 105260 31°38.891 8°06.281", header=TRUE, stringsAsFactors=FALSE) x 

Сама функция использует:

  • strsplit() с шаблоном регулярного выражения "[°\\.]" - это строка, разделенная на один шаг
  • sapply петлю над вектором

Попробуй это:

 convert<-function(x){ z <- sapply((strsplit(x, "[°\\.]")), as.numeric) z[1, ] + z[2, ]/60 + z[3, ]/3600 } 

Попробуй:

 convert(x$long) [1] 9.108611 8.391944 8.111111 8.254722 8.272778 8.178056 

Отказ от ответственности: я не проверял вашу математику. Используйте по своему усмотрению.

Как прокомментировал Джим Льюис, прежде чем кажется, что вы используете минуты с плавающей запятой. Затем вы объединяете только два элемента:

декабрь = с (as.numeric (tmp1 [[1]] [1]), as.numeric (tmp2 [[1]]))

Имея gradleусы, минуты и секунды в форме 43 ° 21’8.02, которая as.character() возвращает «43 ° 21’8.02 \», я обновил вашу функцию до

 convert<-function(coord){ tmp1=strsplit(coord,"°") tmp2=strsplit(tmp1[[1]][2],"'") tmp3=strsplit(tmp2[[1]][2],"\"") dec=c(as.numeric(tmp1[[1]][1]),as.numeric(tmp2[[1]][1]),as.numeric(tmp3[[1]])) c<-abs(dec[1])+dec[2]/60+dec[3]/3600 c<-ifelse(dec[1]<0,-c,c) return(c) } 

добавляя альтернативу для отрицательных координат, и отлично работает для меня. Я все еще не понимаю, почему функция char2dms в библиотеке sp не работает для меня.

благодаря

Другой менее элегантный вариант с использованием подстроки вместо strsplit. Это будет работать, только если все ваши позиции имеют одинаковое количество цифр. Для отрицательных координат просто умножьте на -1 для правильной десятичной степени.

 x$LatDD<-(as.numeric(substring(x$lat, 1,2)) + (as.numeric(substring(x$lat, 4,9))/60)) x$LongDD<-(as.numeric(substring(x$long, 1,1)) + (as.numeric(substring(x$long, 3,8))/60)) 

Спасибо за ответы @Gord Stephen и @CephBirk. Конечно, помог мне. Я думал, что просто упомянул, что я также обнаружил, что measurements::conv_unit не занимают записи «E / W» «N / S», для этого требуются положительные / отрицательные степени. Мои координаты поступают как символьные строки "1 1 1W" и их нужно сначала преобразовать в "-1 1 1" .
Я думал, что поделюсь своим решением.

 df <- c("1 1 1E", "1 1 1W", "2 2 2N","2 2 2S") measurements::conv_unit(df, from = 'deg_min_sec', to = 'dec_deg') [1] "1.01694444444444" NA NA NA Warning message: In split(as.numeric(unlist(strsplit(x, " "))) * c(3600, 60, 1), : NAs introduced by coercion ewns <- ifelse( str_extract(df,"\\(?[EWNS,.]+\\)?") %in% c("E","N"),"+","-") dms <- str_sub(df,1,str_length(df)-1) df2 <- paste0(ewns,dms) df_dec <- measurements::conv_unit(df2, from = 'deg_min_sec', to = 'dec_deg')) df_dec [1] "1.01694444444444" "-1.01694444444444" "2.03388888888889" "-2.03388888888889" as.numeric(df_dec) [1] 1.016944 -1.016944 2.033889 -2.033889 

Посмотрите на degree команды в пакете OSMscale .

  • Как добавить оглавление в Rmarkdown?
  • Формула с динамическим числом переменных
  • Как отлаживать «контрасты могут быть применены только к факторам с 2 или более уровнями»?
  • Создать zip-файл: команда выполнения ошибок "" имеет статус 127
  • Установка старой версии пакета R
  • Как установить размер для локального изображения с помощью knitr для уценки?
  • Создание кадра данных с неравными длинами
  • Добавление новых столбцов в справочную таблицу data.table внутри функции, которая не всегда работает
  • Альтернатива Python xrange для R ИЛИ как петляться над большим набором данных lazilly?
  • Показывать% вместо графов в диаграммах категориальных переменных
  • Выберите группы с более чем одним отдельным значением
  • Давайте будем гением компьютера.