将时间和计数实例分组为R中的12小时箱

时间:2016-06-18 12:16:38

标签: r

我有一个像这样的数据帧df1:

    timestamp
01-12-2015 00:04
01-12-2015 02:20
01-12-2015 02:43
01-12-2015 04:31
01-12-2015 08:51
01-12-2015 11:28
01-12-2015 20:53
01-12-2015 21:28
02-12-2015 00:30
02-12-2015 20:22

其中包含时间戳。我希望通过12小时间隔内的分箱时间来计算,即(01-12-2015 [0-9],01-12-2015 [9-21],依此类推。

输出样本:

DayOfMonth Group count
    1   1   5
    1   2   2
    2   1   2
    2   2   1

每月的日期也可以用序列号替换,从1开始。非常感谢任何帮助解决此问题。

4 个答案:

答案 0 :(得分:3)

基础R中的可能解决方案:

# convert the 'timestamp' column to a datetime format
df1$timestamp <- as.POSIXct(strptime(df1$timestamp, format = '%d-%m-%Y %H:%M'))
# create day.of.month variable
df1$day.of.month <- format(df1$timestamp, '%d')
# extract the 12 hour interval as am/pm values
df1$group <- gsub('[0-9: ]+','\\1',format(df1$timestamp, '%r'))
# aggregate
aggregate(. ~ group + day.of.month, df1, length)

给出:

  group day.of.month timestamp
1    am           01         6
2    pm           01         2
3    am           02         1
4    pm           02         1

使用data.tablepm的{​​{1}}函数的另一种解决方案:

lubridate

给出:

library(lubridate)
library(data.table)
setDT(df1)[, timestamp := dmy_hm(timestamp)
           ][, group := pm(timestamp)+1
             ][, .N, .(day.of.month = day(timestamp),group)]

使用过的数据:

   day.of.month group N
1:            1     1 6
2:            1     2 2
3:            2     1 1
4:            2     2 1

答案 1 :(得分:2)

我们可以使用lubridate函数轻松转换为'Datetime'类,并使用dplyrbase R方法相比有效地获得输出。

library(lubridate)
library(dplyr)
df1 %>% 
    mutate(timestamp = dmy_hm(timestamp)) %>%
    group_by(DayOfMonth = day(timestamp)) %>%
    group_by(Group = as.numeric(cut(timestamp, breaks = "12 hour")), 
            add=TRUE)  %>% 
    summarise(GroupCount = n())
#     DayOfMonth Group GroupCount
#         <int> <dbl>      <int>
#1          1     1          6
#2          1     2          2
#3          2     1          1
#4          2     2          1

或者我们可以使用data.table

的紧凑选项
library(data.table)
setDT(df1)[, {t1 <- dmy_hm(timestamp); .(DayOfMonth = day(t1), 
   Group = (hour(t1)>12)+1L)}][, .(GroupCount = .N), .(DayOfMonth, Group)]
#     DayOfMonth Group GroupCount
#1:          1     1          6
#2:          1     2          2
#3:          2     1          1
#4:          2     2          1

注意:data.table解决方案只需两步即可完成......

数据

df1 <- structure(list(timestamp = c("01-12-2015 00:04", "01-12-2015 02:20", 
"01-12-2015 02:43", "01-12-2015 04:31", "01-12-2015 08:51", "01-12-2015 11:28", 
"01-12-2015 20:53", "01-12-2015 21:28", "02-12-2015 00:30", "02-12-2015 20:22"
)), .Names = "timestamp", class = "data.frame", row.names = c(NA,-10L))

答案 2 :(得分:2)

基础R中的另一种可能的解决方案:

timeStamp <- c("01-12-2015 00:04","01-12-2015 02:20","01-12-2015 02:43","01-12-2015 04:31",
               "01-12-2015 08:51","01-12-2015 11:28","01-12-2015 20:53","01-12-2015 21:28",
               "02-12-2015 00:30","02-12-2015 20:22")
times <- as.POSIXlt(timeStamp,format="%d-%m-%Y %H:%M",tz='GMT')

DF <- data.frame(Times=times)
DF$Group <- as.logical(times$hour > 12) + 1
DF$DayOfMonth <- times$mday

res <- aggregate(Times ~ DayOfMonth + Group,data=DF, FUN = length)

# res :
#   DayOfMonth Group Times
# 1          1     1     6
# 2          2     1     1
# 3          1     2     2
# 4          2     2     1

或者,如果您想在小时范围内包含日期:第二天前一天的[21-0]:

timeStamp <- c("01-12-2015 00:04","01-12-2015 02:20","01-12-2015 02:43","01-12-2015 04:31",
               "01-12-2015 08:51","01-12-2015 11:28","01-12-2015 20:53","01-12-2015 21:28",
               "02-12-2015 00:30","02-12-2015 20:22")
times <- as.POSIXlt(timeStamp,format="%d-%m-%Y %H:%M",tz='GMT')
h <- times$hour + times$min*1/60 + times$sec*1/3600
# here we add 3 hours to the dates in hours range [21-0] in this way we
# push them to the next day
times[h >= 21] <- times[h >= 21] + 3*3600

DF <- data.frame(Times=times)
DF$Group <- ifelse(h < 9,1,ifelse(h <= 21,2,NA))
DF$DayOfMonth <- times$mday

res <- aggregate(Times ~ DayOfMonth + Group,data=na.omit(DF), FUN = length)

# res :
#   DayOfMonth Group Times
# 1          1     1     5
# 2          2     1     2
# 3          1     2     2
# 4          2     2     1

答案 3 :(得分:1)

添加到几个已经提供的选项,stringi包也有一些日期解析函数:

library(stringi)
df1$timestamp <- stri_datetime_parse(df1$timestamp, format = 'dd-mm-yyyy HH:mm')
df1$DayOfMonth <- stri_datetime_format(df1$timestamp, format = 'd')
df1$Group <- stri_datetime_format(df1$timestamp, format = 'a')

之后,您可以使用以下两个选项进行计数:

# option 1:
aggregate(. ~ Group + DayOfMonth, df1, length) # copied from @ProcrastinatusMaximus

# option 2a:
library(dplyr)
df1 %>% 
  group_by(DayOfMonth, Group) %>% 
  tally()

# option 2b:
count(df1, DayOfMonth, Group)

后者的输出:

  DayOfMonth Group     n
       (chr) (chr) (int)
1          1  a.m.     6
2          1  p.m.     2
3          2  a.m.     1
4          2  p.m.     1