【问题标题】:subset a dataframe in R within a specific time range在特定时间范围内对 R 中的数据帧进行子集化
【发布时间】:2021-06-08 08:24:25
【问题描述】:

我有一个名为dataBase 的数据框,其中包含许多行和列。其中一列包含日期(称为日期),而其余列包含数值。下面给出一个简化的表示:

dataBase$date

"30/06/2020" "27/08/2020" "30/06/2020" "28/08/2020" "30/06/2020"
"28/08/2020" "30/06/2020" "01/08/2020" "30/06/2020" "01/08/2020"
"01/08/2020" "30/06/2020" "30/06/2020" "01/08/2020" "30/06/2020"

下面的类

    class(dataBase$date)#"character" 

我想要做的是保留日期在一个范围内的数据框的行,比如说“01/01/2020”-“31/12/2020”。 (提示:这些日期可能不会明确出现在日期列中,仅作为边界日期)

我尝试了不同的方法。一个是使用以下命令:

DATE1 <- as.Date("01/01/2020")
DATE2 <- as.Date("31/12/2020")
TEST <- dataBase[dataBase$date >= DATE1 & dataBase$date <= DATE2,]

TEST <- subset(dataBase, date > as.Date("01/01/2020") & date < as.Date("31/12/2020"))

数据框不受上述命令的影响。

最终,我不得不根据日期列的日期对数据框进行排序,并使用“匹配”来获得相应的位置:

    test4 <- dataBase[order(as.Date(dataBase$date, format="%d/%m/%Y")),]
    forwrd <- sort(as.Date(test4$date, format="%d/%m/%Y"),decreasing = FALSE)
    forwrd <- format(as.Date(forwrd),'%d/%m/%Y')
    rev <- sort(as.Date(test4$date, format="%d/%m/%Y"),decreasing = TRUE)
    rev <- format(as.Date(rev),'%d/%m/%Y')
    start_period = "07/01/2020";end_period = "28/08/2020"
    ind_start<-match(start_period, forwrd)
    ind_end<-length(rev)-match(end_period,rev)+1
    test4_sub <- test4[ind_start:ind_end,];

这给了我行的范围(ind_start - ind_end) 我想问是否有更简单的方法来做到这一点。以及为什么使用前两种方法对我不起作用。

【问题讨论】:

  • 请阅读this 并考虑接受您迄今为止提出的问题的答案。

标签: r dataframe date subset


【解决方案1】:

这是dplyr 解决方案:

library(dplyr)
dataBase %>%
  mutate(date = as.Date(date, format = "%d/%m/%Y")) %>%
  filter(date >= "2020-07-30" & date <= "2020-08-30")
              a       date
V12 -0.23017749 2020-08-28
V13  1.55870831 2020-08-01
V21  0.07050839 2020-08-27
V32 -1.26506123 2020-08-01
V41 -0.44566197 2020-08-28
V43  0.35981383 2020-08-01
V52  0.11068272 2020-08-01

数据:

set.seed(123)
dataBase <- data.frame(a = rnorm(15), date = unlist(read.table(text = '"30/06/2020" "27/08/2020" "30/06/2020" "28/08/2020" "30/06/2020"
"28/08/2020" "30/06/2020" "01/08/2020" "30/06/2020" "01/08/2020"
"01/08/2020" "30/06/2020" "30/06/2020" "01/08/2020" "30/06/2019"')))

【讨论】:

  • 亲爱的 Chris Ruehlemann 和 @Base_R_Best_R,感谢你们提供的非常有用的帮助。两种方法都有效并且很优雅!我对你们俩都投了赞成票。
  • 感谢您的支持。你知道你也可以接受答案吗?选择您最喜欢的答案,然后单击答案左上角的勾号。
【解决方案2】:

您的问题在于正确指定日期格式。我还将最后一个日期更改为您的日期范围之外的日期,否则 data.frame() 将保持不变。

代码

# First convert from charactert to date

dataBase$date <- as.Date(dataBase$date, format = "%d/%m/%Y")

# then find the boolean vector for subsetting

bool <- dataBase$date < as.Date("2020-12-31") & dataBase$date > as.Date("2020-01-01")

# finally use that for subsetting 

dataBase[bool, ]

#              a       date
# V11  1.8071121 2020-06-30
# V12  0.1294905 2020-08-28
# V13 -0.8860187 2020-08-01
# V21 -1.5073589 2020-08-27
# V22  1.2067775 2020-06-30
# V23  1.1733465 2020-06-30
# V31  0.7798806 2020-06-30
# V32 -0.8435670 2020-08-01
# V33  0.8572508 2020-06-30
# V41 -2.3080748 2020-08-28
# V42  1.4869950 2020-06-30
# V43  0.1705372 2020-08-01
# V51  1.8373611 2020-06-30
# V52  0.5101801 2020-08-01

数据

dataBase <- data.frame(a = rnorm(15), date = unlist(read.table(text = '"30/06/2020" "27/08/2020" "30/06/2020" "28/08/2020" "30/06/2020"
"28/08/2020" "30/06/2020" "01/08/2020" "30/06/2020" "01/08/2020"
"01/08/2020" "30/06/2020" "30/06/2020" "01/08/2020" "30/06/2019"')))

dataBase

#              a       date
# V11  1.8071121 30/06/2020
# V12  0.1294905 28/08/2020
# V13 -0.8860187 01/08/2020
# V21 -1.5073589 27/08/2020
# V22  1.2067775 30/06/2020
# V23  1.1733465 30/06/2020
# V31  0.7798806 30/06/2020
# V32 -0.8435670 01/08/2020
# V33  0.8572508 30/06/2020
# V41 -2.3080748 28/08/2020
# V42  1.4869950 30/06/2020
# V43  0.1705372 01/08/2020
# V51  1.8373611 30/06/2020
# V52  0.5101801 01/08/2020
# V53 -0.9052635 30/06/2019

【讨论】:

    猜你喜欢
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 2017-05-12
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 2013-10-25
    相关资源
    最近更新 更多