2017-07-24 1 views
0

Version abrégée: J'ai une trame de données avec deux colonnes: Latitude et Longitude, chacune étant exprimée en degrés, minutes et secondes. Après avoir lu des questions similaires like this one, j'ai décidé d'utiliser le paquet measurements pour effectuer la conversion, mais les résultats sont faussés lors de la conversion d'une unité à une autre (voir ci-dessous).Erreur lors de la conversion des degrés, minutes et secondes en degrés décimaux à l'aide du package de mesures

Version détaillée:

fourni la trame de données suivante où j'ai deux colonnes, Latitude et Longitude exprimées en degrés, minutes et secondes

df = data.frame(
     Latitude = c("15° 33' 9\"",NA,"52° 58' 13\"", NA, "21° 1' 28\"", "21° 2' 26\"", "10° 47' 31\"", NA, "-34° 53' 38\"", "41° 7' 56\""), 
     Longitude = c("48° 30' 59\"", NA, "-3° 10' 13\"", NA, "105° 50' 34\"", "105° 47' 52\"", "106° 41' 29\"", NA, "-56° 8' 16\"", "-104° 46' 30\"")) 

Je veux convertir ces valeurs en degrés décimaux par utilisant le paquet measurements comme suit:

library(measurements) 

# Turn degrees, minutes and seconds into spaces so they can be used with 
# measurements::conv_unit. 
df$Latitude = str_replace(df$Latitude, "°", "") 
df$Latitude = str_replace(df$Latitude, "'", "") 
df$Latitude = str_replace(df$Latitude, "\"", "") 

df$Longitude = str_replace(df$Longitude, "°", "") 
df$Longitude = str_replace(df$Longitude, "'", "") 
df$Longitude = str_replace(df$Longitude, "\"", "") 


# Use measurements::conv_unit to convert to decimal degrees. 
df$Latitude = conv_unit(df$Latitude, "deg_min_sec", "dec_deg") 
df$Longitude = conv_unit(df$Longitude, "deg_min_sec", "dec_deg") 

Cependant, je reçois la sortie suivante:

> df 
     Latitude  Longitude  Latitude_dec Longitude_dec 
1 15° 33' 9" 48° 30' 59"   15.5525 48.5163888888889 
2   <NA>   <NA>    <NA>    <NA> 
3 52° 58' 13" -3° 10' 13"    <NA>    <NA> 
4   <NA>   <NA>   1.4725 50.5958333333333 
5 21° 1' 28" 105° 50' 34" 2.43611111111111 47.8961111111111 
6 21° 2' 26" 105° 47' 52"    <NA>    <NA> 
7 10° 47' 31" 106° 41' 29" 34.8938888888889 56.1377777777778 
8   <NA>   <NA> 41.1322222222222   104.775 
9 -34° 53' 38" -56° 8' 16"    -0    -0 
10 41° 7' 56" -104° 46' 30"    0    -0 

Comme vous pouvez le voir, la première ligne des champs calculés semblent avoir raison, alors en commençant par la ligne 3, les résultats se foiré, et, par conséquent, d'être complètement inutile. J'ai lu ?conv_unit plusieurs fois et je ne trouve aucune erreur. Qu'est-ce que je fais mal?

Répondre

1

conv_unit brise apparemment quand NA présent, probablement à cause de la façon dont il analyse en utilisant unlist(strsplit(... comme dans cette ligne du code source

secs = lapply(split(as.numeric(unlist(strsplit(x, 
       " "))) * c(3600, 60, 1), f = rep(1:length(x), 
       each = 3)), sum) 

Je pense donc que vous devez ignorer NA lors de la conversion, comme ceci:

library(measurements) 

df = data.frame(
    Latitude = c("15° 33' 9\"",NA,"52° 58' 13\"", NA, "21° 1' 28\"", "21° 2' 26\"", "10° 47' 31\"", NA, "-34° 53' 38\"", "41° 7' 56\""), 
    Longitude = c("48° 30' 59\"", NA, "-3° 10' 13\"", NA, "105° 50' 34\"", "105° 47' 52\"", "106° 41' 29\"", NA, "-56° 8' 16\"", "-104° 46' 30\"")) 

# Turn degrees, minutes and seconds into spaces so they can be used with 
# measurements::conv_unit. 
# NOTE THIS CAN BE DONE IN ONE OR TWO LINES USING REGEX "OR" (|) 
# - I would think this could be done in stringr::str_replace too 
# - but I don't know how. 
df$Latitude = gsub("°|'|\"", "", df$Latitude) 
df$Longitude = gsub("°|'|\"", "", df$Longitude) 

# Use measurements::conv_unit to convert to decimal degrees. 
not_na <- !is.na(df$Latitude) #identify non-na (I assume same for Long here) 
#convert only non-na values 
df$Latitude[not_na] = conv_unit(df$Latitude[not_na], "deg_min_sec", "dec_deg") 
df$Longitude[not_na] = conv_unit(df$Longitude[not_na], "deg_min_sec", "dec_deg") 

qui donne

df 
      Latitude   Longitude 
1   15.5525 48.5163888888889 
2    <NA>    <NA> 
3 52.9702777777778 -3.17027777777778 
4    <NA>    <NA> 
5 21.0244444444444 105.842777777778 
6 21.0405555555556 105.797777777778 
7 10.7919444444444 106.691388888889 
8    <NA>    <NA> 
9 -34.8938888888889 -56.1377777777778 
10 41.1322222222222   -104.775 
+0

Merci beaucoup pour votre solution (et améliorations sur mon code). J'ai supposé que cela avait quelque chose à voir avec NA, mais je ne savais pas comment trouver la moindre idée ni comment y faire face. Solution très intelligente! – ccamara