如果在一定时间范围内如何在R中分配值?

时间:2015-08-11 18:48:04

标签: r if-statement

我有一个大型数据集,每天从人们那里收集多个数据点。我的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)编写代码。

我拥有的例子: enter image description here

我想要的例子:(参见新的提示栏) 因此,对于10/11/15,我希望提示1在11:15:00到11:45:00之间,但对于11/11/15,我希望提示1不同 - 在12:00:00和12之间:30:00 enter image description here

3 个答案:

答案 0 :(得分:2)

如果您想使用时间和日期,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
  

答案 1 :(得分:1)

我有一个更简单的解决方案,使用日,小时和分钟以及您可以用作功能的(手动)过滤器。 查看我的简单示例:

 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

答案 2 :(得分:0)

我最终使用了这些答案中的一些。

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小时,但是接下来要玩。谢谢你的帮助!