我正在尝试按Holidays
或Normal
对数据帧中的实例进行分类。
我有必须在list/dataframe
对象中分类为Holidays
的日期,以及要在另一个测试对象中分类的日期。
要分类为Holidays
,除了在必须以这种方式分类的日期之间之外,list/daraframe
列之一中还有一个必须1
而不是0
的Condition
(即,当且仅当相应的Condition
0
时,日期实际介于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