2016-10-07 10 views
0

Гипотетический кадр данных, представляющий стадо овец с чипами rfid на их воротниках. Существуют сборщики данных с модемами, прикрепленными к полюсам по всему полю. Каждое уникальное время, когда уникальная овца попадает в зону действия одного из этих полюсов, она считается «событием», которое хранится в устройстве arduino, прикрепленном к модему на полюсе. Каждое устройство arduino имеет адрес и примерно каждые пять минут, он вызывает через модем, чтобы сообщить о его статусе и количестве событий.R подмножество данных по дате и часу; для цикла или sapply()?

> head(wow) 
    address  checkin_time status_id number_events 
1  11 2016-08-08 00:04:40   7   10 
2  11 2016-08-08 00:09:53   7   13 
3  11 2016-08-08 00:15:06   7   12 
4  11 2016-08-08 00:20:20   7   11 
5  11 2016-08-08 00:25:33   7   13 
6  11 2016-08-08 00:30:45   7    5 

Я пытаюсь создать новую матрицу, которая содержит все уникальные даты как строки, и каждый уникальный час в течение дня, как и столбцы, и их суммируют общее количество событий для этой даты и времени.

Вот мой мой (усеченный) код, который делает это:

allDays <- unique(as.Date(wow$checkin_time)) 
for (d in allDays) { 
oneAM <- subset(wow, as.POSIXct(wow$checkin_time) >= as.POSIXct(paste(d,'00:00:00')) & as.POSIXct(wow$checkin_time) <= as.POSIXct(paste(d, '00:59:59'))) 
twoAM <- subset(wow, as.POSIXct(wow$checkin_time) >= as.POSIXct(paste(d,'01:00:00')) & as.POSIXct(wow$checkin_time) <= as.POSIXct(paste(d, '01:59:59'))) 
threeAM <- subset(wow, as.POSIXct(wow$checkin_time) >= as.POSIXct(paste(d,'02:00:00')) & as.POSIXct(wow$checkin_time) <= as.POSIXct(paste(d, '02:59:59'))) 
enter code here 
. . . 

elevenPM <- subset(wow, as.POSIXct(wow$checkin_time) >= as.POSIXct(paste(d,'22:00:00')) & as.POSIXct(wow$checkin_time) <= as.POSIXct(paste(d, '22:59:59'))) 
twelvePM <- subset(wow, as.POSIXct(wow$checkin_time) >= as.POSIXct(paste(d,'23:00:00')) & as.POSIXct(wow$checkin_time) <= as.POSIXct(paste(d, '23:59:59'))) 
dayAsHours <- c(sum(oneAM$number_events), sum(twoAM$number_events), sum(threeAM$number_events), sum(fourAM$number_events), sum(fiveAM$number_events), sum(sixAM$number_events), 
       sum(sevenAM$number_events), sum(eightAM$number_events), sum(nineAM$number_events), sum(tenAM$number_events), sum(elevenAM$number_events), 
       sum(twelveAM$number_events), sum(onePM$number_events), sum(twoPM$number_events), sum(threePM$number_events), sum(fourPM$number_events), 
       sum(fivePM$number_events), sum(sixPM$number_events), sum(sevenPM$number_events), sum(eightPM$number_events), sum(ninePM$number_events), 
       sum(tenPM$number_events), sum(elevenPM$number_events), sum(twelvePM$number_events)) 
dateMatrix <- rbind(dateMatrix, dayAsHours) 
} 

Приведенный выше код работает для одного значения d, когда это было жестко закодированы в, но перестал работать, когда я окружил его в for-loop.

Ошибки я получаю:

Error in as.POSIXlt.character(x, tz, ...) : 
character string is not in a standard unambiguous format 

Кроме того, я знаю, что, вероятно, следует использовать sapply() вместо for-loop здесь, но я с трудом выяснить, как построить функцию. Будет ли wow быть ресурсом данных, к которому будет применена функция, или это будет allDays?

Любая точка в правильном направлении была бы чрезвычайно полезна.

+1

'cut' будет работать на данном POSIXt, так что вы могли бы создайте две переменные: одну с датой, а затем другую с временными интервалами, сокращенными по часам, и используйте ** data.table ** или ** dplyr ** для объединения с этими двумя, а затем измените форму перемещения по часовой стрелке на колонны. – joran

ответ

1

Один из подходов, чтобы сделать то, что я считаю нужным, - использовать format, чтобы удалить дату и час с checkin_time. Затем с помощью dplyr:

library(dplyr) 
library(tidyr) 
result <- wow %>% mutate(Date=format(checkin_time, format="%Y-%m-%d"), 
         Hour=format(checkin_time, format="%H")) %>% 
        group_by(Date,Hour) %>% 
        summarise(number_events=sum(number_events)) %>% 
        spread(Hour, number_events) 

Примечания:

  1. Использования mutate для создания столбцов Date и Hour от оголенного дня и часа от checkin_time.
  2. group_byDate и Hour и использовать summarise для sum всех number_events для каждого Date и Hour.
  3. Используйте spread от tidyr, чтобы создать результат табуляции с помощью Date в виде строк и Hours в виде столбцов.

Я изменил свои входные данные, размещенные wow, чтобы добавить больше даты и часы:

wow <- structure(list(address = c(11L, 11L, 11L, 11L, 11L, 11L), checkin_time = structure(c(1470629080, 
1470629393, 1470716106, 1470720020, 1470803133, 1470803445), class = c("POSIXct", 
"POSIXt"), tzone = ""), status_id = c(7L, 7L, 7L, 7L, 7L, 7L), 
    number_events = c(10L, 13L, 12L, 11L, 13L, 5L)), .Names = c("address", 
"checkin_time", "status_id", "number_events"), row.names = c(NA, 
-6L), class = "data.frame") 
## address  checkin_time status_id number_events 
##1  11 2016-08-08 00:04:40   7   10 
##2  11 2016-08-08 00:09:53   7   13 
##3  11 2016-08-09 00:15:06   7   12 
##4  11 2016-08-09 01:20:20   7   11 
##5  11 2016-08-10 00:25:33   7   13 
##6  11 2016-08-10 00:30:45   7    5 

Используя эти данные:

print(result) 
##Source: local data frame [3 x 3] 
##Groups: Date [3] 
## 
##  Date 00 01 
##*  <chr> <int> <int> 
##1 2016-08-08 23 NA 
##2 2016-08-09 12 11 
##3 2016-08-10 18 NA 
+0

Спасибо, это блестяще. Раньше я не смотрел на dlplyr, но я думаю, мне нужно узнать, что библиотека поспешила. – OnlyDean