在参考数据框中的两个日期之间查找观测日期,并为R中的所有观测报告另一个参考值

时间:2019-02-06 04:16:42

标签: r

我有一个与c观测值相关的日期。 2000个观测值,并想为我的观测数据“季节”添加一个新因素。每个日期都属于一个季节,以开始和结束日期为界。我在一个小的参考数据框中输入了季节,开始日期和结束日期,想查询观察日期并推断出它属于哪个季节,介于哪个季节和开始日​​期之间。

我尝试了内部函数和间隔函数的各种组合,但是无法报告季节值。

https://rdrr.io/cran/lubridate/man/within-interval.html

在堆栈交换时也曾提出过类似的问题,但措辞不够清晰,无法给出对我有帮助的适用答案。

我的参考数据如下:

Season <- c("A","B","C","D","E","F","G","H","I","J","K")
Start <- c("29-Apr-12","19-Oct-12",
           "29-Apr-13","19-Oct-13",
           "29-Apr-14","19-Oct-14",
           "29-Apr-15","19-Oct-15",
           "29-Apr-16","19-Oct-16",
           "29-Apr-17")
Start <- as.Date (Start,"%d-%b-%y")
End <-  c("18-Oct-12","28-Apr-13",
          "18-Oct-13","28-Apr-14",
          "18-Oct-14","28-Apr-15",
          "18-Oct-15","28-Apr-16",
          "18-Oct-16","28-Apr-17",
          "18-Oct-17")
End <- as.Date (End,"%d-%b-%y")
Reference.df <- data.frame(Season,Start,End)
> Reference.df
  Season      Start        End
       A 2012-04-29 2012-04-29
       B 2012-10-19 2012-10-19
       C 2013-04-29 2013-04-29
       D 2013-10-19 2013-10-19
       E 2014-04-29 2014-04-29
       F 2014-10-19 2014-10-19
       G 2015-04-29 2015-04-29
       H 2015-10-19 2015-10-19
       I 2016-04-29 2016-04-29
       J 2016-10-19 2016-10-19
       K 2017-04-29 2017-04-29

我的观察数据如下:

 Date <-  c("25-Apr-14","03-May-14","24-Nov-15","16-Feb-14","02-May-14","21- 
 Apr-17","27-Apr-15","27-Apr-13", "12-Aug-16","16-Apr-14")
 Date <- as.Date (Date,"%d-%b-%y")
 Observation <- seq(1,10)
 Data.df <- data.frame(Observation,Date)
> Data.df
  Observation       Date
            1 2014-04-25
            2 2014-05-03
            3 2015-11-24
            4 2014-02-16
            5 2014-05-02
            6 2017-04-21
            7 2015-04-27
            8 2013-04-27
            9 2016-08-12
           10 2014-04-16

我想要的输出如下:

> Data.df
      Observation       Date Season
                1 2014-04-25      D
                2 2014-05-03      E
                3 2015-11-24      H
                4 2014-02-16      D
                5 2014-05-02      E
                6 2017-04-21      J
                7 2015-04-27      F
                8 2013-04-27      B
                9 2016-08-12      I
               10 2014-04-16      D

2 个答案:

答案 0 :(得分:1)

我认为这已经被询问过了,但目前找不到相关的帖子。

无论如何,为了回答您的问题,我们可以使用sapply并检查每个DateStart中的EndReference.df日期之间的位置,然后提取相应的Season

Data.df$Season <- sapply(Data.df$Date, function(x) 
        Reference.df$Season[x >= Reference.df$Start & x <= Reference.df$End])


Data.df
#   Observation       Date Season
#1            1 2014-04-25      D
#2            2 2014-05-03      E
#3            3 2015-11-24      H
#4            4 2014-02-16      D
#5            5 2014-05-02      E
#6            6 2017-04-21      J
#7            7 2015-04-27      F
#8            8 2013-04-27      B
#9            9 2016-08-12      I
#10          10 2014-04-16      D

这是假设每个季节我们有唯一的StartEnd日期,并且不会有重叠。如果存在重叠,我们可以使用which.max来获取介于两者之间的第一个Season

sapply(Data.df$Date, function(x) 
  Reference.df$Season[which.max(x >= Reference.df$Start & x <= Reference.df$End)])

或者使用cut更好的选择,假设Seasons接连不断

cut(as.numeric(Data.df$Date), 
 breaks = c(-Inf, Reference.df$Start[-1], Inf), labels =  Reference.df$Season)

#[1] D E H D E J F B I D

答案 1 :(得分:0)

使用dplyrmagrittr并不会像sapply那样节省您很多时间,但是如果您与其他人共享,则操作起来会更容易一些-经验丰富的同事:

library(dplyr)
library(magrittr)

Data.df <- Data.df %>% mutate(Season = case_when(Date > as.Date("2012-04-29") & Date < as.Date("2012-10-18")~"A",
                                                 Date > as.Date("2012-10-19") & Date < as.Date("2013-04-28")~"B",
                                                 Date > as.Date("2013-04-29") & Date < as.Date("2013-10-18")~"C",
                                                 Date > as.Date("2013-10-19") & Date < as.Date("2014-04-28")~"D",
                                                 Date > as.Date("2014-04-29") & Date < as.Date("2014-10-18")~"E",
                                                 Date > as.Date("2014-10-19") & Date < as.Date("2015-04-28")~"F",
                                                 Date > as.Date("2015-04-29") & Date < as.Date("2015-10-18")~"G",
                                                 Date > as.Date("2015-10-19") & Date < as.Date("2016-04-28")~"H",
                                                 Date > as.Date("2016-04-29") & Date < as.Date("2016-10-18")~"I",
                                                 Date > as.Date("2016-10-19") & Date < as.Date("2017-04-28")~"J",
                                                 Date > as.Date("2017-04-29") & Date < as.Date("2017-10-18")~"K"))
Data.df

#Observation     Date        Season
#1             2014-04-25      D
#2             2014-05-03      E
#3             2015-11-24      H
#4             2014-02-16      D
#5             2014-05-02      E
#6             2017-04-21      J
#7             2015-04-27      F
#8             2013-04-27      B
#9             2016-08-12      I
#10            2014-04-16      D