0

Hello I have a set of data that holds Latitude and Longitude Coordinates in the format: "22.0N", "2.0E" and I want to be able to work with that data numerically. I'm new to R, so I'm wondering if anyone can help me convert the column of data (fbdata$Latitude (Deg)) to something more usable. i.e. Southern latitudes and Eastern Longitudes negative and without any letters so that I can change it from a character class. This was the code I came up with that obviously doesn't work (thats why I'm here!)

for (i in fbdata$Latitude..Deg.) {
  if (endsWith(fbdata$Latitude..Deg.[i],"S")) {
    print (fbdata$Latitude..Deg.[i]) #paste0 ("-",fbdata$Latitude..Deg.)
  }
}

Any help would be great!

Phil
  • 7,287
  • 3
  • 36
  • 66
  • This question will be much easier to answer if you provide a sample of your data. Copy the output of the `dput(head(fbdata))` command, click the [edit] button under your post and, paste the output into your question . Please see [How to make a great R reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) for more information. – Ian Campbell Apr 23 '21 at 02:40

2 Answers2

1

You can do this using tidyr's separate() function.

First we split into two columns to separate the direction from the degree. I've chosen to keep the old column using remove = FALSE in case you need it for other purposes. sep = -1 splits off the last character i.e. the direction. Once you have the degree on its own you should be able to use as.numeric to convert it.

fbdata %>%
separate(col = Latitude..Deg., into = c('degree', 'direction'), sep = -1, remove = FALSE) %>%
mutate(degree = as.numeric(degree))

Then for the positive/negative, for cases where the direction is South or East we multiply the degree column by -1 to flip the sign. When the direction is not either of those two, we leave it as it is.

Following on from the above code:

%>% mutate(degree = case_when(direction %in% c('S', 'E') ~ degree*(-1), TRUE ~ degree))

Or just using ifelse(), which I personally find easier to read:

fbdata$degree <- ifelse(fbdata$direction %in% c('S', 'E'), fbdata$degree*(-1), fbdata$degree)
Elle
  • 998
  • 7
  • 12
  • The `separate` function is from the `tidyr` package, not `dplyr`. – www Apr 23 '21 at 01:59
  • Ah, thanks for the heads up. I always use them together so they're not very well `separate`d in my head! – Elle Apr 23 '21 at 02:04
  • Thanks Elle! I was having some trouble getting it to come through though. When I would run those lines (note I adjusted the names because I'm only dealing with Latitude at the moment, I get the following error. Error in `$<-.data.frame`(`*tmp*`, Lat_Degree, value = logical(0)) : replacement has 0 rows, data has 92 – Tyler Virkler Apr 23 '21 at 03:45
  • Could you tell me which line gives you that error? – Elle Apr 23 '21 at 03:51
  • I run this: `library(dplyr) library(tidyr) fbdata %>% separate(col = Latitude..Deg., into = c('Lat_Degree', 'Lat_Direction'), sep = -1, remove = FALSE) %>% mutate(Lat_Degree = as.numeric(Lat_Degree)) fbdata$Lat_Degree <- ifelse(fbdata$Lat_Direction %in% c('S'), fbdata$Lat_Degree*(-1), fbdata$Lat_Degree)` and it spits out this error: `Error in `$<-.data.frame`(`*tmp*`, Lat_Degree, value = logical(0)) : replacement has 0 rows, data has 92` – Tyler Virkler Apr 23 '21 at 03:57
  • Try running it one line at a time to see which line the error comes from. That code works for me on this toy data `c('22N', '3.0S', '51.0S', '28N')` – Elle Apr 23 '21 at 04:03
0

Thanks Elle, but I was actually able to do it using built-in R functions, maybe the extra packages were causing an issue. This is my code to separate the column and adjust the direction numerically.

fbdata$Lat_Degree <- sapply(strsplit(fbdata$Latitude..Deg.,"(?=[A-Z])", perl = TRUE),'[', 1)
fbdata$Lat_Direction <- sapply(strsplit(fbdata$Latitude..Deg.,"(?=[A-Z])", perl = TRUE),'[', 2)
fbdata$Lat_Degree = as.numeric(fbdata$Lat_Degree)
ifelse(fbdata$Lat_Direction == "S", fbdata$Lat_Degree * (-1), fbdata$Lat_Degree)