在R中循环超过两个标准

时间:2016-04-02 01:57:14

标签: r

我有一个看起来像这样的数据框

Spot_Datetime      State 
----------        ------
2016-01-02 08:00   CA
2016-01-02 08:03   AZ

我有另一个看起来像这样的数据框

Datetime           State    Sessions
----------        ------  ----------- 
2016-01-02 08:01   CA        1
2016-01-02 08:02   CA        4
2016-01-02 08:03   CA        3
2016-01-02 08:03   AZ        9

我目前有一个循环,它将第一个数据集中特定时间窗口的会话数相加,但我希望它在状态和日期上匹配。我怎么能在R中这样做?

理想情况下,我的数据框看起来像这样(例如,10分钟的窗口):

Spot_Datetime      State   Sessions
----------        ------   ---------
2016-01-02 08:00   CA         8
2016-01-02 08:03   AZ         9

我有一个上下窗口循环,我可以在外循环上使用If语句吗?

数据

d1 <- read.table(header = TRUE, text = "Spot_Datetime      State 
'2016-01-02 08:00'   CA
'2016-01-02 08:03'   AZ", colClasses = c('POSIXct','character'))

d2 <- read.table(header = TRUE, text = "Datetime           State    Sessions
'2016-01-02 08:01'   CA        1
'2016-01-02 08:02'   CA        4
'2016-01-02 08:03'   CA        3
'2016-01-02 08:03'   AZ        9", colClasses = c('POSIXct','character','integer'))

2 个答案:

答案 0 :(得分:1)

您只想按州按间隔分组,并使用您熟悉的任何方法。这是基地

d1 <- read.table(header = TRUE, text = "Spot_Datetime      State 
                 '2016-01-02 08:00'   CA
                 '2016-01-02 08:03'   AZ", colClasses = c('POSIXct','character'))

d2 <- read.table(header = TRUE, text = "Datetime           State    Sessions
                 '2016-01-02 08:01'   CA        1
                 '2016-01-02 08:02'   CA        4
                 '2016-01-02 08:03'   CA        3
                 '2016-01-02 08:03'   AZ        9", colClasses = c('POSIXct','character','integer'))

所以这里的想法是在第二个数据集中花费时间(按状态)并使用一个窗口从&#34;键&#34;创建一些间隔。数据集,我们将用它作为额外的分组变量来获得总和。

例如,我们可以每隔1分钟剪切0到60分钟,看看d2中的日期时间落在哪一个(POSIXct计数秒,所以我们必须乘以60)

window <- 1
findInterval(d2$Datetime, d1$Spot_Datetime[1] + seq(0, 60, by = window) * 60)
# [1] 2 3 4 4

window <- 10
findInterval(d2$Datetime, d1$Spot_Datetime[1] + seq(0, 60, by = window) * 60)
# [1] 1 1 1 1

现在只需按州执行。唯一的技巧是匹配d1中哪些字段与d2

对齐
window <- 10
d3 <- merge(d2, d1, sort = FALSE)
d3$idx <- ave(1:nrow(d3), d3$State, FUN = function(x)
  findInterval(d3$Datetime[x], unique(d3$Spot_Datetime[x]) + seq(0, 60, window) * 60))

(d4 <- aggregate(Sessions ~ State + idx, d3, sum))

#   State idx Sessions
# 1    AZ   1        9
# 2    CA   1        8

merge(d1, d4[, c('State','Sessions')], sort = FALSE)

#   State       Spot_Datetime Sessions
# 1    CA 2016-01-02 08:00:00        8
# 2    AZ 2016-01-02 08:03:00        9

答案 1 :(得分:0)

这是使用dplyr包而不是循环的解决方案。首先,定义时间窗口是什么。其次,根据Datetime列将数据切割成窗口。 (我使用了一个10分钟的窗口,因此您提供的数据只能在单个窗口中切换,但这应该适用于更长时间段内的更多数据。)最后,组按日期时间和状态的数据,并对每个组内的会话求和。

# (Read in your d2 data)

# get 10-min cut points
start <- as.POSIXct("2016-01-02 08:00")  #Set beginning of first window in data
end <- as.POSIXct("2016-01-02 08:10")    #Set end of last window in data
winsize <- 60*10    # set window size in seconds
winbreaks <- seq(start, end, by=winsize)

# Cut the data based on the windows, 
# group it by window and State, 
# then sum Sessions within each group
results <- data %>% mutate(window=cut(Datetime, breaks=winbreaks)) %>%
                 group_by(window, State) %>%
                 summarise(tot.sessions=sum(Sessions))

如果您以前没有使用它,dplyr语法可能需要一些时间来习惯。但是一旦你开始使用它就很容易掌握它,并且它通常比循环快得多,并且可能不太容易出现编码错误。

注意:我不确定你的d1桌在这个角色扮演什么角色;看起来你可以用d2做你想做的事,除非d2有时间戳和d1中你想要从结果中排除的状态。如果是这种情况,请查看dplyr过滤器并加入函数。