我有一个看起来像这样的数据框
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'))
答案 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
过滤器并加入函数。