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

conv_unit()函数在ifelse()语句中无法正常运行的问题排查

问题:度分十进制转十进制度时ifelse()调用conv_unit()报错且结果异常

需求

需要将表格中混合存在的两种地理坐标格式(十进制度dec_deg、度分十进制deg_dec_min)统一转换为十进制度,使用dplyr::mutate()结合ifelse()调用measurements::conv_unit()时出现警告,且转换结果不符合预期。

可复现代码

library(dplyr)
library(measurements)

data_latlon <- tibble(latitude = c(8.726088, -16.365242, -19.888074, 
                                   '1 40.232', '0 2.308', '2 2.356'),
                      longitude = c(-83.180764, -62.015502, -40.549983, 
                                    '75 54.301', '70 56.693', '72 41.143'), 
                      unit = c('dec_deg', 'dec_deg', 'dec_deg', 
                               'deg_dec_min', 'deg_dec_min','deg_dec_min'))

场景1:全局使用ifelse()的问题

执行以下代码后出现警告,且latitude列转换结果错误:

data_latlon %>% 
  mutate(latitude = ifelse(unit=='deg_dec_min', 
                           conv_unit(latitude, from = 'deg_dec_min', to = 'dec_deg'), 
                           latitude))

输出结果:

# A tibble: 6 × 3
  latitude         longitude  unit       
  <chr>            <chr>      <chr>      
1 8.726088         -83.180764 dec_deg    
2 -16.365242       -62.015502 dec_deg    
3 -19.888074       -40.549983 dec_deg    
4 2.34133333333333 75 54.301  deg_dec_min
5 2.356            70 56.693  deg_dec_min
6 0                72 41.143  deg_dec_min

警告信息:

Warning messages:
1: Problem while computing `latitude = ifelse(...)`.
ℹ longer object length is not a multiple of shorter object length 
2: Problem while computing `latitude = ifelse(...)`.
ℹ data length is not a multiple of split variable 

场景2:单独过滤后处理正常

仅筛选unit='deg_dec_min'的行时,转换结果正确:

data_latlon %>% 
  filter(unit=='deg_dec_min') %>% 
  mutate(latitude = ifelse(unit=='deg_dec_min', 
                           conv_unit(latitude, from = 'deg_dec_min', to = 'dec_deg'), 
                           latitude))

输出结果:

# A tibble: 3 × 3
  latitude           longitude unit       
  <chr>              <chr>     <chr>      
1 1.67053333333333   75 54.301 deg_dec_min
2 0.0384666666666667 70 56.693 deg_dec_min
3 2.03926666666667   72 41.143 deg_dec_min

问题原因

ifelse()会将整个latitude向量传入conv_unit(),而该列同时包含十进制度的字符型数值(如"8.726088")和度分十进制格式的字符串(如"1 40.232")。conv_unit()无法正确解析十进制度格式的字符串,导致处理后的结果向量长度与原向量不匹配,进而触发警告并返回错误的转换值。

解决方案

可以通过逐行处理或严格的条件分支匹配来解决,以下是两种可行方法:

方法1:使用rowwise()逐行处理

rowwise()会让mutate()对每一行单独执行计算,确保conv_unit()只接收符合格式的字符串:

data_latlon %>%
  rowwise() %>%
  mutate(latitude = ifelse(unit == 'deg_dec_min',
                           conv_unit(latitude, from = 'deg_dec_min', to = 'dec_deg'),
                           latitude)) %>%
  ungroup() %>%
  mutate(latitude = as.numeric(latitude)) # 统一转换为数值类型

方法2:使用case_when()结合类型转换

case_when()可以更清晰地定义分支逻辑,同时确保两边返回值类型一致:

data_latlon %>%
  mutate(latitude = case_when(
    unit == 'deg_dec_min' ~ conv_unit(latitude, from = 'deg_dec_min', to = 'dec_deg') %>% as.numeric(),
    TRUE ~ as.numeric(latitude)
  ))

两种方法最终都会得到正确的转换结果:

# A tibble: 6 × 3
  latitude longitude  unit       
     <dbl>     <dbl>  <chr>      
1   8.7261   -83.181 dec_deg    
2 -16.3652   -62.016 dec_deg    
3 -19.8881   -40.550 dec_deg    
4   1.6705    75.905 deg_dec_min
5   0.0385    70.945 deg_dec_min
6   2.0393    72.686 deg_dec_min

内容的提问来源于stack exchange,提问作者Florencia Grattarola

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 13:17:13