You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于最近可用年份的土地覆盖数据生成新分类变量的R语言实现需求

基于最近可用年份的土地覆盖数据生成新分类变量的R语言实现

嗨,我来帮你搞定这个需求!咱们的目标是根据每条记录的Year字段,匹配到最新的可用土地覆盖数据年份,再把对应的LandcoverXXXXSub_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可能不够高效,可以考虑用tidyrpivot_longer把宽表转成长表,再匹配年份,这样代码更简洁也更高效,需要的话可以告诉我哦~
  • 两种编码规则你可以根据实际需求选择,规则二更直观,能从编号直接看出原始的Landcover和Sub_landcover分类。

备注:内容来源于stack exchange,提问作者student

火山引擎 最新活动