如何通过left_join替换数据框中的NA值,保留非NA值不变?
仅针对缺失经纬度的地点回填地理编码数据
以下是完整的实现方案,既能避免重复调用耗时的地理编码接口,又能精准回填缺失值并保留原有有效数据:
1. 加载依赖包与定义原数据框
library(tidyverse) library(tmaptools) # 原地点数据框 df_places <- tibble( place_country = c("Melbourne, Australia", "Sydney, Australia", "Brisbane, Australia"), state = c("VIC", "NSW", "QLD"), temperature = c("Cold", "Cool", "Hot"), lon = c(41.23, NA, 43.55), lat = c(NA, -88.10, -80.48) )
2. 仅对缺失经纬度的地点调用地理编码
# 筛选出经纬度存在缺失的地点,调用OSM地理编码接口获取数据 df_geocodes <- df_places %>% filter(is.na(lat) | is.na(lon)) %>% select(place_country) %>% bind_cols( tmaptools::geocode_OSM( q = .$place_country, as.data.frame = TRUE )[,c("lon", "lat")] )
3. 回填经纬度并保留原有非NA值
# 关联原数据与地理编码结果,替换NA值 df_places_updated <- df_places %>% left_join(df_geocodes, by = "place_country", suffix = c("_original", "_geocoded")) %>% mutate( # 优先保留原数据的非NA值,原数据为NA时用地理编码结果替换 lon = coalesce(lon_original, lon_geocoded), lat = coalesce(lat_original, lat_geocoded) ) %>% select(-ends_with("_original"), -ends_with("_geocoded")) # 清理临时列
最终结果
执行后得到的更新数据框:
# A tibble: 3 × 4 place_country state temperature lon lat <chr> <chr> <chr> <dbl> <dbl> 1 Melbourne, Australia VIC Cold 145. -37.8 2 Sydney, Australia NSW Cool 151. -33.9 3 Brisbane, Australia QLD Hot 43.6 -80.5
核心逻辑说明
filter(is.na(lat) | is.na(lon)):精准定位需要补全的地点,避免对已有有效数据重复调用地理编码,大幅节省耗时left_join:确保原数据的所有行都被保留,同时匹配到对应的地理编码结果coalesce():按顺序取第一个非NA值,完美实现"保留原值、替换缺失"的需求- 最后清理临时生成的后缀列,让结果数据框与原结构保持一致
内容的提问来源于stack exchange,提问作者Cameron
相关产品推荐
相关产品推荐

