我是R的新手,并且在功能能够对整个矢量进行操作而不必明确指定这一事实的情况下挣扎。
我有一个包含多列的数据框calls
,其中一列是“日期”列。现在我想添加一个新列“白天”,用于标记特定条目日期所在的白天:
> calls
call_id length date direction daytime
1 258 531 1400594572974 outgoing afternoon
2 259 0 1375555528144 unanswered evening
3 260 778 1385922648396 incoming evening
我已经实现了返回类似布尔值向量的方法:
# Operates on POSIXlt timestamps
is.earlymorning <- function(date) {
hour(floor_date(date, "hour")) >= 5 & hour(floor_date(date, "hour")) < 9
}
调用is.earlymorning(“2014-05-20 16:02:52”, “2013-08-03 20:45:28”, “2013-12-01 19:30:48”)
因此将返回(“FALSE”,“FALSE”,“FALSE”)。我目前正在努力的是实现一个实际返回标签的函数。我希望该功能的作用如下:
# rawDate is a long value of the date as ms since 1970
Daytime <- function(rawDate) {
date <- as.POSIXlt(as.numeric(rawDate) / 1000, origin = "1970-01-01")
if (is.earlymorning(date)) {
"earlymorning"
} else if (is.morning(date)) {
"morning"
} else if (is.afternoon(date)) {
"afternoon"
} else if (is.evening(date)) {
"evening"
} else if (is.earlynight(date)) {
"earlynight"
} else if (is.latenight(date)) {
"latenight"
}
}
显然,我的上述方法不起作用,因为在我的例子中,if条件将对整个向量进行操作。有没有一种优雅的方法来解决这个问题?我确信我很困惑或遗漏了一些重要的观点,但正如我所提到的,我对R很新。
简而言之,我想要实现的是一个根据日期值向量返回标签向量的函数:
# Insert new column with daytime labels
calls$daytime <- Daytime(df$date)
# or something like that:
calls$daytime <- sapply(df$date, Daytime)
# Daytime(1400594572974, 1375555528144, 1385922648396) => (“afternoon”, “evening”, “evening”)
答案 0 :(得分:3)
一种方法是使用cut
而不是ifelse
。我不完全确定你想要标记时间,但这会给你一个想法。 foo是你的数据(即电话)。
library(dplyr)
# Following your idea
ana <- transform(foo, date = as.POSIXlt(as.numeric(date) / 1000, origin = "1970-01-01"))
ana %>%
mutate(hour = cut(as.numeric(format(date, "%H")),
breaks = c(00,04,08,12,16,20,24),
label = c("late night", "early morning",
"morning", "afternoon",
"evening", "early night")
)
)
# call_id length date direction daytime hour
#1 258 531 2014-05-20 23:02:52 outgoing afternoon early night
#2 259 0 2013-08-04 03:45:28 unanswered evening late night
#3 260 778 2013-12-02 03:30:48 incoming evening late night
答案 1 :(得分:1)
不需要有6种不同的功能来确定给定日期的某一时段。定义一个匹配小时和白天的向量就足够了。例如:
Daytime<-function(rawDate) {
#change the vector according to your definition of the daytime.
#the first value corresponds to hour 0 and the last to hour 23
hours<-c(rep("latenight",5),rep("earlymorning",4),rep("morning",4),rep("afternoon",4),rep("evening",4),rep("earlynight",3))
hours[as.POSIXlt(as.numeric(rawDate) / 1000, origin = "1970-01-01")$hour+1]
}
答案 2 :(得分:0)
鉴于Thomas&#39;提示,我解决了我的问题,以下(不可思议的方式):
Daytime <- function(rawDates) {
dates <- as.POSIXlt(as.numeric(rawDates) / 1000, origin = "1970-01-01")
ifelse(is.earlymorning(dates), "earlymorning",
ifelse(is.morning(dates), "morning",
ifelse(is.afternoon(dates), "afternoon",
ifelse(is.evening(dates), "evening",
ifelse(is.earlynight(dates), "earlynight",
ifelse(is.latenight(dates), "latenight",
"N/A")
)
)
)
)
)
}
考虑到更多标签的情况,这种方法很快就会无法维持。现在它符合我的目的,我会留下它,因为我必须尽快集中精力分析数据。但是如果我有时间离开并找到一个不太复杂的解决方案,我会告诉你的!感谢您的快速回复,Thomas。