【问题标题】:Find date elements in Dataframe Column that matches specific condition in R在数据框列中查找与 R 中的特定条件匹配的日期元素
【发布时间】:2018-05-30 13:01:53
【问题描述】:

我正在尝试通过HolidaysNormal 对数据框中的实例进行分类。

我有必须在list/dataframe 对象中归类为Holidays 的日期和我想在另一个测试对象中归类的日期。

要分类为Holidays,除了在必须以这种方式分类的日期之间之外,list/daraframe 列之一中的Condition 必须是1 而不是0(即,当且仅当对应的 Condition0 时,日期实际上介于 Holidays 日期之间的实例应标记为 Normal

对象包含应标记为Holidays数据库天:

holidays2015 <- list(list("2015-01-01",1,1,1),
                     list("2015-01-06",0,1,1),
                     list("2015-03-19",0,1,1),
                     list("2015-04-02",0,1,1),
                     list("2015-04-03",0,1,1),
                     list("2015-05-01",1,1,1),
                     list("2015-05-02",0,1,1),
                     list("2015-05-15",0,1,1),
                     list("2015-06-04",0,1,1),
                     list("2015-08-15",1,1,0),
                     list("2015-10-12",1,1,1),
                     list("2015-11-09",0,1,1),
                     list("2015-12-08",1,1,0),
                     list("2015-12-24",0,0,1),
                     list("2015-12-25",1,1,0),
                     list("2015-12-31",0,0,1))

holidays2014 <- list(list("2014-01-01",1,1,1),
                     list("2014-01-06",0,1,1),
                     list("2014-04-17",0,1,1),
                     list("2014-04-18",0,1,1),
                     list("2014-05-01",1,1,1),
                     list("2014-05-02",0,1,0),
                     list("2014-05-15",0,1,1),
                     list("2014-06-19",0,1,1),
                     list("2014-08-15",1,1,1),
                     list("2014-11-01",1,1,0),
                     list("2014-11-10",0,1,1),
                     list("2014-12-06",1,1,1),
                     list("2014-12-08",1,1,0),
                     list("2014-12-25",1,1,1))
totalholidays <- list(holidays2015, holidays2014)
dfholidays <- lapply(totalholidays, function(x) data.table::rbindlist(x))
dfholidays <- data.table::rbindlist(dfholidays)
names(dfholidays) <- c("Date", "V2", "V3", "Condition")

我要标记的日期:

mytestingdates <- as.data.frame(list("Date" = c("2014-01-07", "2014-08-15", 
"2015-06-04", "2015-08-15")))

我的工作解决方案是 for bucle:

慢路

holidaysvector <- c()
for (ii in 1:nrow(mytestingdates)){
  if (mytestingdates$Date[ii] %in% dfholidays$Date){
    tmp <- which(dfholidays$Date == mytestingdates$Date[ii])
    if (dfholidays$Condition[tmp] == 1) {
      holidaysvector <- c(holidaysvector, "Holidays")
    } else { holidaysvector <- c(holidaysvector, "Normal T.1") }
    } else { holidaysvector <- c(holidaysvector, "Normal T.2") }
}
mytestingdates$forsolution <- holidaysvector
rm(tmp)

但我想要一个更有效的解决方案。我尝试了一些 R 选项但失败了:

R 想要看起来相似的解决方案:

mytestingdates$MyRtry <- ifelse(mytestingdates$Date %in% dfholidays$Date, 
ifelse(dfholidays$Condition == 1, "Holiday", "Normal T.1"), "Normal T.2")

所需的解决方案

        Date     MyRtry forsolution
1 2014-01-07 Normal T.2  Normal T.2
2 2014-08-15    Holiday    Holidays
3 2015-06-04    Holiday    Holidays
4 2015-08-15    Holiday  Normal T.1

请注意,实例 4 位于 Holidays 对象中,但它的 condition 为 0,因此它被标记为 Normal 天,这在我的 R 解决方案中被遗漏了。

有什么想法吗?任何关于干净代码的建议或从我的代码派生的编程技术都将非常受欢迎。

【问题讨论】:

  • 也许我在您的描述中遗漏了它,但是“V2”和“V3”列是什么?
  • 对不起,如果不清楚,它们并不重要,你可以忽略它们,它们是原始数据集的一部分,但对于这种情况并不重要。

标签: r date dplyr


【解决方案1】:

您愿意接受 dplyr 解决方案吗?

library(dplyr)
mytestingdates %>% 
  left_join(dfholidays) %>% 
  mutate(forsolution = ifelse(is.na(Condition), "Normal T.2", ifelse(Condition == 0, "Normal T.1", "Holidays"))) 

dfholidays 在这里加入了 mytestingdates。如果 mytestingdates 中的日期不在 dfholidays 中,它只会合并这些日期的 NA。因此,您可以检查 Condition 是否为 NA,如果是,则将 forsolution 设置为“Normal T.2”。随后,您检查 Condition == 0,如果是,则让 forsolution 为“Normal T.1”。在其他情况下,解决方案将是“假期”。

        Date V2 V3 Condition forsolution
1 2014-01-07 NA NA        NA  Normal T.2
2 2014-08-15  1  1         1    Holidays
3 2015-06-04  0  1         1    Holidays
4 2015-08-15  1  1         0  Normal T.1

更新:更短的是:

mytestingdates %>% 
  left_join(dfholidays) %>% 
  mutate(forsolution = case_when(is.na(Condition) ~ "Normal T.2", Condition == 0 ~ "Normal T.1",  TRUE ~ "Holidays"))

【讨论】:

  • 感谢您的回答,它帮助我解决了问题并学习了其他编程思路。
【解决方案2】:

这个方案不区分NormalT1和NormalT2,但是很简单:

mytestingdates["classifier"] <- ifelse(mytestingdates$Date %in% dfholidays[dfholidays$Condition==1]$Date,"Holiday", "Normal")

mytestingdates

        Date classifier
1 2014-01-07     Normal
2 2014-08-15    Holiday
3 2015-06-04    Holiday
4 2015-08-15     Normal

【讨论】:

  • 我不确定您是否需要区分 NormalT1 和 NormalT2,或者您是否这样做是为了让事情变得更容易。
  • 我只是添加它们以阐明被归类为“正常”的原因,但不,两者之间没有实际区别。非常感谢提供代码,我知道会有一种超快的方法,但可以找到它。
猜你喜欢
  • 2021-02-12
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
  • 2018-11-07
  • 1970-01-01
  • 2019-10-11
  • 2012-11-19
  • 1970-01-01
相关资源
最近更新 更多