基于最近可用年份的土地覆盖数据生成新分类变量的R语言实现需求
基于最近可用年份的土地覆盖数据生成新分类变量的R语言实现
嗨,我来帮你搞定这个需求!咱们的目标是根据每条记录的Year字段,匹配到最新的可用土地覆盖数据年份,再把对应的LandcoverXXXX和Sub_landcoverXXXX组合成一个包含40类的新变量Actual_landcover。下面是具体的实现步骤和代码:
第一步:明确年份匹配规则
首先得理清每个Year对应的参考土地覆盖年份:
- 给定的土地覆盖数据年份是2013、2015、2017、2019、2021
- 对于任意
Year,我们要选择小于等于该Year的最大土地覆盖年份:- 2014 → 2013
- 2016 → 2015
- 2017 → 2017
- 2023 → 2021
第二步:R代码实现
首先先把你提供的示例数据加载进来,同时把字符型的数值转成数值类型(方便后续计算):
# 加载示例数据 df <- data.frame( ID = c("1", "2", "3", "4", "5"), Year = c("2014", "2014", "2016", "2017", "2023"), Landcover2013 = c("1", "1", "2", "1", "4"), Landcover2015 = c("1", "1", "3", "2", "4"), Landcover2017 = c("1", "1", "2", "2", "3"), Landcover2019 = c("2", "1", "2", "2", "4"), Landcover2021 = c("2", "1", "3", "1", "4"), Sub_landcover2013 = c("4", "7", "5", "9", "1"), Sub_landcover2015 = c("5", "7", "6", "9", "2"), Sub_landcover2017 = c("4", "6", "6", "9", "1"), Sub_landcover2019 = c("4", "6", "6", "9", "2"), Sub_landcover2021 = c("4", "6", "6", "10", "1") ) # 将字符型数值转为数值类型 df <- df %>% mutate(across(c(Year, starts_with("Landcover"), starts_with("Sub_landcover")), as.numeric))
接下来,我们定义参考年份列表,然后为每条记录匹配对应的参考年份,再提取对应的土地覆盖和子分类值:
library(dplyr) # 定义可用的土地覆盖年份 ref_years <- c(2013, 2015, 2017, 2019, 2021) # 为每条记录匹配对应的参考年份 df <- df %>% mutate( ref_year = sapply(Year, function(y) max(ref_years[ref_years <= y])), # 根据参考年份提取对应的Landcover值 selected_landcover = case_when( ref_year == 2013 ~ Landcover2013, ref_year == 2015 ~ Landcover2015, ref_year == 2017 ~ Landcover2017, ref_year == 2019 ~ Landcover2019, ref_year == 2021 ~ Landcover2021 ), # 根据参考年份提取对应的Sub_landcover值 selected_sub = case_when( ref_year == 2013 ~ Sub_landcover2013, ref_year == 2015 ~ Sub_landcover2015, ref_year == 2017 ~ Sub_landcover2017, ref_year == 2019 ~ Sub_landcover2019, ref_year == 2021 ~ Sub_landcover2021 ) )
最后,根据你给出的两种编码规则生成Actual_landcover:
规则一:连续编号((Landcover-1)*10 + Sub_landcover)
比如Landcover1+Sub4=4,Landcover2+Sub1=11,和你第一个示例规则一致:
df <- df %>% mutate(Actual_landcover_rule1 = (selected_landcover - 1)*10 + selected_sub)
规则二:组合编号(Landcover*10 + Sub_landcover)
比如Landcover1+Sub4=14,Landcover2+Sub1=21,和你第二个示例规则一致(也符合你给出的最终输出示例):
df <- df %>% mutate(Actual_landcover_rule2 = selected_landcover*10 + selected_sub)
第三步:查看最终结果
如果只保留ID和你想要的Actual_landcover(比如用规则二),可以这样提取:
final_result <- df %>% select(ID, Actual_landcover = Actual_landcover_rule2) print(final_result)
运行后会得到和你给出的示例一致的结果:
ID Actual_landcover 1 1 14 2 2 17 3 3 36 4 4 29 5 5 41
补充说明
- 如果你的实际数据量很大,用
case_when可能不够高效,可以考虑用tidyr的pivot_longer把宽表转成长表,再匹配年份,这样代码更简洁也更高效,需要的话可以告诉我哦~ - 两种编码规则你可以根据实际需求选择,规则二更直观,能从编号直接看出原始的Landcover和Sub_landcover分类。
备注:内容来源于stack exchange,提问作者student




