簡體   English   中英

如果在特定時間范圍內,如何在 R 中賦值?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM