![](/img/trans.png)
[英]With R, how do i assign values to a new column based on numbers that fall within a range?
[英]How do I assign a value in R if within a certain range of time?
我有一个大数据集,每天从人们那里收集多个数据点。 我的 R 数据集包含参与者的响应和他们响应的时间戳。 我想重新编码时间戳以反映他们响应的订单提示。 所以基本上,我想根据时间范围为时间戳分配一个值。 因此,如果在星期一,响应落在 10:00 和 10:30 之间,我希望值为 1。如果响应落在 12:15 和 12:45 之间,我希望值为 2。如果响应下降在 2:20 和 2:50 之间,我希望该值为 3。
但我需要该代码仅适用于周一的数据。 对于星期二的数据,时间戳范围会发生变化。 例如,如果星期二响应介于 9:10 和 9:40 之间,则该值应为 1。依此类推。
我一生都无法用 if else 语句来解决这个问题。 当我将时间写入 R 时,它认为我正在为一系列值(10 到 30)而不是时间(10:30)编写代码。
我想要的示例:(请参阅新的提示列)因此,对于 10/11/15,我希望提示 1 落在 11:15:00 和 11:45:00 之间,但是对于 11/11/15,我想要提示 1有所不同——在 12:00:00 和 12:30:00 之间
如果您想处理时间和日期,POSIXlt 类会很有帮助。 如果您的时间戳存储为字符串,则第一步是将它们转换为 POSIXlt。 您可以为此使用“strptime”,例如
> t <- strptime("2015-01-01 12:18",format="%Y-%m-%d %H:%M")
> t
[1] "2015-01-01 12:18:00 CET"
> class(t)
[1] "POSIXlt" "POSIXt"
>
以下函数“timerange”为此类 POSIXlt 对象分配时间范围编号:
R <- list( Sun = list(),
Mon = list( c("10:00","10:30"), c("12:15","12:40"), c("13:15","13:40") ),
Tue = list( c( "9:10", "9:40"), c("11:00","11:30"), c("13:15","13:40") ),
Wed = list( c("10:00","10:30"), c("12:15","12:40"), c("13:15","13:40") ),
Thu = list( c("10:00","10:30"), c("12:15","12:40"), c("13:15","13:40") ),
Fri = list( c("10:00","10:30"), c("12:15","12:40"), c("13:15","13:40") ),
Sat = list( c("10:00","10:30"), c("12:15","12:40"), c("13:15","13:40") ) )
timerange <- function(t)
{
s <- unlist(strsplit(strftime(t,format="%Y-%m-%d %H:%M:%S %w")," "))
w <- as.numeric(s[3]) + 1
n <- sapply(R[[w]], function(x){ strptime(paste(s[1]," ",x,":00",sep=""),
format="%Y-%m-%d %H:%M:%S")})
return( which(sapply(n,function(x){ t-x[1]>=0 & t-x[2]<=0})) )
}
“R”是所有时间范围的列表。 您可以随心所欲地更改它。 "strftime" 是 "strptime" 的对应物,即将 POSIXlt 对象 "t" 转换为所需格式的字符串。 然后将该字符串分成日期部分、时间部分和星期几。 后者用于在“R”中选择合适的子列表。 然后“strptime”用于创建POSIXlt 对象对的列表。 时间部分来自“R”的相应子列表,日期部分来自“t”。 每个这样的对代表一个时间间隔。 那么时间范围编号是包含“t”的时间间隔的索引。
一些例子:
> t <- strptime("2015-01-01 12:18",format="%Y-%m-%d %H:%M")
> timerange(t)
[1] 2
> t <- strptime("2015-01-05 10:01",format="%Y-%m-%d %H:%M")
> timerange(t)
[1] 1
> t <- strptime("05.01.2015 13:25",format="%d.%m.%Y %H:%M")
> timerange(t)
[1] 3
我有一个更简单的解决方案,使用天数、小时数和分钟数以及您可以将其用作函数的(手动)过滤器。 检查我的简单示例:
library(lubridate)
# example dataset
dt = data.frame(responce = 1:3,
date = c("2015-08-10 10:15:34","2015-08-10 12:29:14","2015-08-11 09:12:18"),
stringsAsFactors = F)
dt
# responce date
# 1 1 2015-08-10 10:15:34
# 2 2 2015-08-10 12:29:14
# 3 3 2015-08-11 09:12:18
# transform to date and obtain day, hour and minutes
dt$date = ymd_hms(dt$date)
dt$day = wday(dt$date, label=T)
dt$hour = hour(dt$date)
dt$minute = minute(dt$date)
dt
# responce date day hour minute
# 1 1 2015-08-10 10:15:34 Mon 10 15
# 2 2 2015-08-10 12:29:14 Mon 12 29
# 3 3 2015-08-11 09:12:18 Tues 9 12
# create a column with an arbitrary value to start with and also double check in the end
dt$value = -1
# conditions for Monday
dt$value[dt$day=="Mon" & dt$hour==10 & dt$minute >= 0 & dt$minute <=30] = 1
dt$value[dt$day=="Mon" & dt$hour==12 & dt$minute >= 15 & dt$minute <=45] = 2
dt$value[dt$day=="Mon" & dt$hour==14 & dt$minute >= 20 & dt$minute <=50] = 3
# conditions for Tuesday
dt$value[dt$day=="Tues" & dt$hour==9 & dt$minute >= 10 & dt$minute <=40] = 1
dt
# responce date day hour minute value
# 1 1 2015-08-10 10:15:34 Mon 10 15 1
# 2 2 2015-08-10 12:29:14 Mon 12 29 2
# 3 3 2015-08-11 09:12:18 Tues 9 12 1
# double check all your rows matched (you have no -1 values)
dt[dt$value == -1]
# data frame with 0 columns and 3 rows
我最终使用了这两个答案中的一些。
library(lubridate)
#change data to POSIXct class
data$StartDate <- dmy(as.character(data$StartDate))
data$EndDate <- dmy(as.character(data$EndDate))
data$StartTime2 <- hms(as.character(data$StartTime))
data$EndTime2 <- hms(as.character(data$Endataime))
我不必两者都做,但我还是做了。 我创建了一个额外的变量,因为改变它会让它看起来很有趣。
#check me out
class(data$StartDate)
#[1] "POSIXct" "POSIXt"
class(data$StartTime2)
#[1] "Period"
#attr(,"package")
#[1] "lubridate"
根据第二条评论,我做了:
data$day = wday(data$StartDate, label=T)
data$hour = hour(data$StartTime2)
data$minute = minute(data$StartTime2)
# create a column with an arbitrary value to start with and also double check in the end
data$prompt = -1
# conditions for Tuesday (10/11/2015)
data$prompt[data$day=="Tues" & data$hour==11 & data$minute >= 10 & data$minute <=40] = 1
data$prompt[data$day=="Tues" & data$hour==13 & data$minute >= 35 & data$minute <=59] = 2
data$prompt[data$day=="Tues" & data$hour==16 & data$minute >= 15 & data$minute <=45] = 3
等等。 我知道我必须为这一天修复提示 2,因为它进入了第 14 小时,但这是接下来要玩的。 谢谢你的帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.