我有一个包含变量的数据集 “年”(2014-2023), 'Landcover2013'(分类变量 1-4), '土地覆盖2015', '土地覆盖2017', '土地覆盖2019', '2021 年土地覆盖', 'Sub_landcover2013'(子类别 1-10), 'Sub_landcover2015', 'Sub_landcover2017', 'Sub_landcover2019', 'Sub_landcover2021'。
由于存在多个变量,数据很难使用。我想要一个单一变量,它结合了“LandcoverXXXX”和“Sub_landcoverXXXX”变量的信息。
我需要有一列包含描述土地覆盖的分类变量(4 x 10 = 40,因此理论上,由于所有这些类别和子类别,值的范围可以从 1 到 40)。而且由于土地覆盖值存在时间变化,我希望该条款利用基于变量“Year”的最新可用数据。例如,如果“Year”是 2014 年,则用于新值的数据来自变量“Landcover2013”和“Sub_landcover2013”。例如,对于 2015 年“Year”,我想使用 2013 年的相同数据,因为土地覆盖数据是在名称中提到的那些年份的末尾发布的。我希望下面的示例表能够澄清我的问题。
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"),
NEW_COLUMN = c("4", "7", "26", "19", "31"))
我该怎么做?谢谢您的帮助!
使用
tidyverse
包,这是实现您目标的方法。工作流程:
pivot_longer()
slice()
每个组按“group1”列中小于“Year”列的最大年份pivot_wider()
获得两个独立的土地覆盖类型列library(dplyr)
library(tidyr)
library(stringr)
result <- df %>%
pivot_longer(-c(id, Year, NEW_COLUMN)) %>%
mutate(group = case_when(str_detect(name, "^Land") ~ "landcover",
TRUE ~ "sub_landcover"),
group1 = as.integer(str_sub(name, start= -4))) %>%
group_by(id, group) %>%
slice(which.min(abs(as.integer(Year) - group1))) %>%
ungroup() %>%
pivot_wider(id_cols = c(id,Year),
names_from = group,
values_from = value)
result
# A tibble: 5 × 4
id Year landcover sub_landcover
<chr> <chr> <chr> <chr>
1 1 2014 1 4
2 2 2014 1 7
3 3 2016 3 6
4 4 2017 2 9
5 5 2023 4 1