You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R语言中提取坐标字符串数值并添加负号生成新列

处理带方向标识的地理坐标转换问题

问题背景

现有包含1800行数据的数据集,其中LATITUD(纬度)、LONGITUD(经度)列是带有N(北纬)/S(南纬)/W(西经)标识的地理坐标字符串。需要完成以下操作:

  • 提取坐标中的数值部分
  • 当坐标为S(南纬)或W(西经)时,为数值添加负号
  • 生成新列用于地图绘制

当前使用的正则表达式未达到预期效果,现寻求正确实现方法。

测试数据集与当前代码

test <- structure(list(GNUMBER = c("G12879D", "G13004A", "G51770", "G51771", 
"G51772", "G10017", "G12862", "G19898A", "G51361", "G51664B", 
"G51665", "G51665A", "G51666", "G51663", "G51663A", "G51664", 
"G51664A", "G51653C", "G51652B"), LATITUD = c("18.35N", NA, "20.62N", 
"20.62N", "20.62N", "19.00N", "19.78N", "27.34S", "27.39S", "9.90N", 
"9.90N", "9.90N", "9.90N", "9.90N", "9.90N", "9.90N", "9.90N", 
"9.90N", "9.90N"), LONGITUD = c("99.99W", NA, "101.72W", "101.72W", 
"101.72W", "99.11W", "103.11W", "65.96W", "65.98W", "83.93W", 
"83.93W", "83.93W", "83.93W", "83.93W", "83.93W", "83.93W", "83.93W", 
"83.93W", "83.93W")), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -19L))

library(tidyverse)
library(stringr)

regexp <- "[^1:9]+$"

test %>%
  mutate(LATITUD_NEW = str_extract(test$LATITUD, regexp))  

解决方案

当前正则表达式[^1:9]+$逻辑错误,它匹配的是非1-9字符的结尾部分,因此只会提取到方向标识(如N/S/W)而非数值。以下是两种高效的修正方案:

方法1:结合parse_number与方向判断

利用readr::parse_number自动提取数值,再通过case_when根据方向符号添加正负号,逻辑清晰易维护:

library(tidyverse)

test_processed <- test %>%
  mutate(
    # 处理纬度:南纬S对应负数值,北纬N对应正数值
    LATITUD_NEW = case_when(
      str_detect(LATITUD, "S") ~ -parse_number(LATITUD),
      str_detect(LATITUD, "N") ~ parse_number(LATITUD),
      TRUE ~ NA_real_  # 保留原数据中的NA值
    ),
    # 处理经度:西经W对应负数值,若有东经E可添加`str_detect(LONGITUD, "E") ~ parse_number(LONGITUD)`规则
    LONGITUD_NEW = case_when(
      str_detect(LONGITUD, "W") ~ -parse_number(LONGITUD),
      TRUE ~ NA_real_
    )
  )

# 查看转换结果
test_processed %>% select(GNUMBER, LATITUD, LATITUD_NEW, LONGITUD, LONGITUD_NEW)

方法2:正则替换生成带符号字符串再转数值

通过正则替换直接生成带负号的字符串,再转换为数值类型,适合对正则熟悉的场景:

library(tidyverse)

test_processed <- test %>%
  mutate(
    LATITUD_NEW = str_replace(LATITUD, "^(\\d+\\.\\d+)(S)$", "-\\1") %>% 
      str_replace("^(\\d+\\.\\d+)(N)$", "\\1") %>% 
      as.numeric(),
    LONGITUD_NEW = str_replace(LONGITUD, "^(\\d+\\.\\d+)(W)$", "-\\1") %>% 
      as.numeric()
  )

两种方法均能正确处理原数据中的NA值,生成符合地图绘制要求的带符号坐标数值列。

内容的提问来源于stack exchange,提问作者Miguel Angel Acosta Chinchilla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 02:35:22