在数据帧列中查找与 R 中的特定条件匹配的日期元素



我正在尝试按HolidaysNormal对数据帧中的实例进行分类。

我有必须在list/dataframe对象中分类为Holidays的日期,以及要在另一个测试对象中分类的日期。

要分类为Holidays,除了在必须以这种方式分类的日期之间之外,list/daraframe列之一中还有一个必须1而不是0Condition(即,当且仅当相应的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

请注意,实例 no.4 在Holidays对象中,但其condition为 0,因此它被标记为Normal天,这在我的 R 解决方案中丢失了。

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

你对dplyr解决方案持开放态度吗?

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

在这里,dfholidays加入了mytestingdate。如果 mytestingdate 中的日期不在 dfholidays 中,则它仅合并这些日期的 NA。因此,您可以检查条件是否为NA,如果是,则将解决方案设置为"正常T.2"。随后,您检查条件 == 0,如果是,则让 forsolution 为"正常 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"))

此解决方案不区分 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

最新更新