【问题标题】:R: Adding columns and rows of data based on multiple conditions on a existing dataframeR:根据现有数据框上的多个条件添加数据的列和行
【发布时间】:2022-01-09 08:24:15
【问题描述】:

我想重组我的土地利用分类数据框,并根据数据框的条件添加新的行和列。我一直在使用 dplyr 进行尝试,但是我发现的示例倾向于减少列或行,而不是根据条件增加行数。我试图遍历数据集以添加行,但想知道在 dplry 中是否有更好的方法?我也愿意使用不同的库,但它的分类数据集非常大,dplyr 似乎可以很好地与数据框配合使用?

这是我当前数据框的代码示例 (df_old) 以及我希望它最终的样子 (df_new)。

我想要做的是,每次 Year1990-2015 更改它都会创建一个新行。示例:ID 424,在 1990 年为 51,但在 2000 年更改为 21 并保持 21 直到今天。这意味着 ID 424 的新数据框应该有两行。一个标有 Start_Year 的标签表示 1990 年土地利用的开始为 Forest (Landuse = 51),并且在 2000 年发生变化之前一直是 Forest。由于 2000 年它是 Pavement,我们假设它在 1999 年仍然是 Forest,而 End_Year 将是 1999 年ID 424 的第一行。然后,ID 424 出现一个新行,其中 Start_Year 为 2000,因为它更改为 Pavement (Landuse = 21),并且在 End_year(现在)之前保持 21。

为了添加上下文,数据集表示城市中区域的变化情况,其中 1990-2015 年的数字用于识别不同的土地利用分类(21 = 路面,24 = 公园,25 = 住宅,51 = 森林,41 = 农业)。

df_old <- data.frame(ID = c(424,426,427,428),
             Parameter= c(0.01,0.03,0.03,0.01),
             City = c("Abbotsford","Abbotsford","Abbotsford","Abbotsford"),
             Area = c(3.12,7.98,2.01,0.48),
             Year1990 = c(51,51,51,41),
             Year2000 = c(21,51,51,41),
             Year2005 = c(21,51,51,25),
             Year2010 = c(21,51,51,24),
             Year2015 = c(21,51,51,25))

df_new <- data.frame(ID = c(424,424,426,427,428,428,428,428),
             Parameter= c(0.01,0.01,0.03,0.03,0.01,0.01,0.01,0.01),
             City = c("Abbotsford","Abbotsford","Abbotsford","Abbotsford","Abbotsford","Abbotsford","Abbotsford","Abbotsford"),
             Area = c(3.12,3.12,7.98,2.01,0.48,0.48,0.48,0.48),
             Start_Year = c(1990,2000,1990,1990,1990,2005,2010,2015),
             End_Year = c(1999,"present","present","present",2004,2009,2014,"present"),
             Landuse = c("51-51","51-21","51-51","51-51","41-41","41-25","25-24","24-25"))

这就是我想要的最终产品:

【问题讨论】:

  • 我对“结束”列感到困惑 - 在原始日期 (df__old) 的哪个位置出现 2014current 值?另外,您如何形成LU-LU 列?我建议编辑您的帖子以更明确地说明需要做什么。
  • 谢谢,我已经添加了一些说明

标签: r dataframe dplyr conditional-statements


【解决方案1】:

此解决方案适用于您的示例数据,但很难确定管理您所需操作的“规则”(因此很难知道它是否适用于您的真实数据)。如果您的真实数据失败,请使用更多信息编辑您的帖子。

library(tidyverse)

df_old <- data.frame(ID = c(424,426,427,428),
                     Parameter= c(0.01,0.03,0.03,0.01),
                     City = c("Abbotsford","Abbotsford","Abbotsford","Abbotsford"),
                     Area = c(3.12,7.98,2.01,0.48),
                     Year1990 = c(51,51,51,41),
                     Year2000 = c(21,51,51,41),
                     Year2005 = c(21,51,51,25),
                     Year2010 = c(21,51,51,24),
                     Year2015 = c(21,51,51,25))

df_new <- data.frame(ID = c(424,424,426,427,428,428,428,428),
                     Parameter= c(0.01,0.01,0.03,0.03,0.01,0.01,0.01,0.01),
                     City = c("Abbotsford","Abbotsford","Abbotsford","Abbotsford","Abbotsford","Abbotsford","Abbotsford","Abbotsford"),
                     Area = c(3.12,3.12,7.98,2.01,0.48,0.48,0.48,0.48),
                     Start = c(1990,2000,1990,1990,1990,2005,2010,2015),
                     End = c(1999,"present","present","present",2004,2009,2014,"present"),
                     LU = c("51-51","51-21","51-51","51-51","41-41","41-25","25-24","24-25"))


df_old %>%
  pivot_longer(cols = -c(1:4)) %>%
  group_by(ID) %>%
  mutate(Start = as.numeric(str_extract(name, "\\d+"))) %>%
  mutate(`LU-LU` = paste(lag(value, default = max(value)), "-", value, sep = "")) %>%
  distinct(`LU-LU`, .keep_all = TRUE) %>%
  group_by(ID) %>%
  filter(value != lag(value, default = 0)) %>%
  group_by(ID) %>%
  mutate(End = lead(Start, default = NA) - 1,
         End = replace_na(End, "present")) %>%
  select(c(ID, Parameter, City, Area, Start, End, `LU-LU`))
#> # A tibble: 8 × 7
#> # Groups:   ID [4]
#>      ID Parameter City        Area Start End     `LU-LU`
#>   <dbl>     <dbl> <chr>      <dbl> <dbl> <chr>   <chr>  
#> 1   424      0.01 Abbotsford  3.12  1990 1999    51-51  
#> 2   424      0.01 Abbotsford  3.12  2000 present 51-21  
#> 3   426      0.03 Abbotsford  7.98  1990 present 51-51  
#> 4   427      0.03 Abbotsford  2.01  1990 present 51-51  
#> 5   428      0.01 Abbotsford  0.48  1990 2004    41-41  
#> 6   428      0.01 Abbotsford  0.48  2005 2009    41-25  
#> 7   428      0.01 Abbotsford  0.48  2010 2014    25-24  
#> 8   428      0.01 Abbotsford  0.48  2015 present 24-25

reprex package (v2.0.1) 于 2021-12-03 创建

【讨论】:

  • 哇,这看起来棒极了!我看到它使用 tidyr 和 stringr。我已经用较小的数据集对其进行了测试,它似乎已经成功了!我将在一夜之间在大型数据集上运行它,看看是否有任何有趣的错误。但它看起来棒极了!谢谢!
  • 不客气;很高兴它解决了您的问题。感谢您编辑您的问题以包含更多详细信息
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-09
相关资源
最近更新 更多