首页 > 解决方案 > 从列名中提取日期以创建时间序列

问题描述

我有一个带有评估地点的数据框,计算不同的植被指数和不同的日期。我需要在一个新的 data.frame 中加入所有信息,其中嵌入在植被指数中的日期信息包含在输出数据帧的单独列中。

我的数据框具有以下结构:

df.16 <- data.frame(ID=c("a","b","c"),
                    SUGAR=c(152232.92, 117937.06, 72080.81), 
                    EVI_20160616_re=c(0.51, 0.59, 0.37), # The date is included in the column name.
                    EVI_20161006_re=c(0.59, 0.34, 0.46),
                    GNDVI_20160616_re=c(0.51, 0.59, 0.37),
                    GNDVI_20161006_re=c(0.59, 0.34, 0.46),
                    NDVI_20160616_re=c(0.51, 0.59, 0.37),
                    NDVI_20161006_re=c(0.59, 0.34, 0.46),
                    stringsAsFactors=FALSE)

我想获得一个具有以下结构的新 data.frame,这样每个观测值(行)都会列出给定日期和评估地点的植被指数(EVI、GNDVI 和 NDVI)和 SUGAR 列。

在此处输入图像描述

标签: rindexingtime-seriestidyr

解决方案


使用 R 4.0 和最新版本的 tidyr (1.1.0) 和 dplyr (1.0.0),pivot_longer()支持将列名拆分为窄格式数据集中的多个变量。拆分后,我们可以使用pivot_wider()为 和 创建EVI列。由于输入数据框中的变量名称部分似乎无关紧要,我们使用将它们从输出中删除。GNDVINDVI_reselect()

df.16 <- data.frame(ID=c("a","b","c"),
                    SUGAR=c(152232.92, 117937.06, 72080.81), 
                    EVI_20160616_re=c(0.51, 0.59, 0.37), # The date is included in the column name.
                    EVI_20161006_re=c(0.59, 0.34, 0.46),
                    GNDVI_20160616_re=c(0.51, 0.59, 0.37),
                    GNDVI_20161006_re=c(0.59, 0.34, 0.46),
                    NDVI_20160616_re=c(0.51, 0.59, 0.37),
                    NDVI_20161006_re=c(0.59, 0.34, 0.46),
                    stringsAsFactors=FALSE) 
library(tidyr)
library(dplyr)
df.16 %>% 
     pivot_longer(.,-c(ID,SUGAR),names_to=c("variable","DATE","RE"),
                  names_sep = "_",values_to = "value") %>%
     select(-RE) %>% 
     pivot_wider(.,c(ID,DATE,SUGAR),names_from=variable,values_from=value)

...和输出:

# A tibble: 6 x 6
  ID    DATE       SUGAR   EVI GNDVI  NDVI
  <chr> <chr>      <dbl> <dbl> <dbl> <dbl>
1 a     20160616 152233.  0.51  0.51  0.51
2 a     20161006 152233.  0.59  0.59  0.59
3 b     20160616 117937.  0.59  0.59  0.59
4 b     20161006 117937.  0.34  0.34  0.34
5 c     20160616  72081.  0.37  0.37  0.37
6 c     20161006  72081.  0.46  0.46  0.46

注意:虽然小数点右侧的数据SUGAR没有打印在输出中,但通过将结果转换为as.data.frame()one 可以看出数据是准确的。

如果我们需要将日期值转换为 R 中的 Date 对象,我们可以添加mutate()进行转换:

df.16 %>% group_by(ID,SUGAR) %>% 
     pivot_longer(.,-c(ID,SUGAR),names_to=c("variable","DATE","RE"),
                  names_sep = "_",values_to = "value") %>%
     select(-RE) %>% 
     pivot_wider(.,c(ID,DATE,SUGAR),names_from=variable,values_from=value) %>%
     mutate(DATE = as.Date(DATE,"%Y%m%d"))

...和输出:

# A tibble: 6 x 6
# Groups:   ID, SUGAR [3]
  ID    DATE         SUGAR   EVI GNDVI  NDVI
  <chr> <date>       <dbl> <dbl> <dbl> <dbl>
1 a     2016-06-16 152233.  0.51  0.51  0.51
2 a     2016-10-06 152233.  0.59  0.59  0.59
3 b     2016-06-16 117937.  0.59  0.59  0.59
4 b     2016-10-06 117937.  0.34  0.34  0.34
5 c     2016-06-16  72081.  0.37  0.37  0.37
6 c     2016-10-06  72081.  0.46  0.46  0.46

推荐阅读