如何基于行值(Site)与列名(日期)匹配填充R语言数据框?
基于行值与列名的匹配填充方案
需求说明
创建与SiteData结构一致的新数据框,规则如下:
SiteData中原本为NA的单元格,新数据框保持NASiteData中非NA的单元格,根据Site字段和日期列名,替换为WeatherData中对应Site、对应日期的天气数值
原数据定义
# 原数据框 SiteData SiteData <- data.frame( Site = c("Apple", "Apple", "Pear"), ID = c(1:3), `1/1/2020` = c(NA,1,1), `1/8/2020` = c(1,1,1), `1/15/2020` = c(1,0,NA), `1/22/2020` = c(0,NA,NA), check.names = FALSE ) # 天气数据框 WeatherData WeatherData <- data.frame( Site = c("Apple", "Pear"), `1/1/2020` = c(5,8), `1/8/2020` = c(7,10), `1/15/2020` = c(2,3), `1/22/2020` = c(1,2), check.names = FALSE )
方法一:使用tidyverse工具包(推荐)
通过长格式转换实现匹配,逻辑清晰易维护:
library(tidyverse) # 将SiteData转为长格式,筛选非NA记录 site_long <- SiteData %>% pivot_longer(cols = -c(Site, ID), names_to = "Date", values_to = "Value") %>% filter(!is.na(Value)) # 将WeatherData转为长格式,便于匹配 weather_long <- WeatherData %>% pivot_longer(cols = -Site, names_to = "Date", values_to = "Weather") # 合并数据、替换值后转回宽格式 result <- SiteData %>% pivot_longer(cols = -c(Site, ID), names_to = "Date", values_to = "Value") %>% left_join(weather_long, by = c("Site", "Date")) %>% mutate(Value = ifelse(!is.na(Value), Weather, NA)) %>% select(-Weather) %>% pivot_wider(names_from = "Date", values_from = "Value") # 查看结果 print(result)
方法二:基础R实现(无需额外包)
通过矩阵索引直接匹配替换:
# 提取日期列名 date_cols <- colnames(SiteData)[-c(1,2)] # 复制原数据作为结果基础 result_base <- SiteData # 遍历日期列完成匹配替换 for (col in date_cols) { # 获取当前列非NA的行索引 non_na_rows <- which(!is.na(SiteData[[col]])) # 匹配对应Site的天气数据 matched_weather <- WeatherData[match(SiteData$Site[non_na_rows], WeatherData$Site), col] # 替换目标单元格 result_base[non_na_rows, col] <- matched_weather } # 查看结果 print(result_base)
最终输出结果
两种方法均会得到如下结果:
Site ID 1/1/2020 1/8/2020 1/15/2020 1/22/2020 1 Apple 1 NA 7 2 1 2 Apple 2 5 7 2 NA 3 Pear 3 8 10 NA NA
内容的提问来源于stack exchange,提问作者CorinthianHelm
相关产品推荐
相关产品推荐

