2017-10-12 1 views
2

시간별, 그룹별로 시계열 데이터를 채울 방법을 찾고있었습니다. 내가 사용하고있는 매우 비효율적 인 방식은 그룹당 데이터 집합을 split으로 설정하고 해당 목록의 모든 요소에서 사용자 정의 시계열 채우기 기능 (최대와 최소 사이의 시퀀스 생성 및 병합)을 적용하는 것입니다. 말할 필요도없이,이 작업은 분할을 통과하지 않을 것입니다.효율적인 시간별 그룹 채우기

내 데이터 세트의 모습

,

source     grp cnt 
1:  83 2017-06-06 13:00:00 1 
2:  83 2017-06-06 23:00:00 1 
3:  83 2017-06-07 03:00:00 1 
4:  83 2017-06-07 07:00:00 2 
5:  83 2017-06-07 13:00:00 1 
6:  83 2017-06-07 19:00:00 1 
7:  83 2017-06-08 00:00:00 1 
8:  83 2017-06-08 14:00:00 1 
9:  83 2017-06-08 15:00:00 1 
10:  83 2017-06-08 20:00:00 1 
11: 137 2017-06-04 02:00:00 1 
12: 137 2017-06-04 05:00:00 1 
13: 137 2017-06-04 23:00:00 1 
... 

내 시도는 complete 기능을 이용하여 tidyverse 방법을 사용하는 것이 었습니다 즉

library(tidyverse) 

d1 %>% 
group_by(source) %>% 
complete(source, grp = seq(min(grp), max(grp), by = 'hour')) 

그러나, 약 40-45초 후, 진행 막대가 나타났습니다 (이 경우에는 약간의 깔끔한 기능에서 분명히 깔끔한 특징이 있습니다 - 나는이 경우 complete을 의심합니다). 완료까지 9 시간. 내 데이터 세트는 매우 커서이 작업은 가장 가벼운 작업이 아니므로 정말 효율적으로 원하는 작업을 찾을 수 있습니다.

데이터

#dput(d1) 
structure(list(source = c("83", "83", "83", "83", "83", "83", 
"83", "83", "83", "83", "137", "137", "137", "137", "137", "137", 
"137", "137", "137", "137", "137", "137", "137", "137"), grp = structure(c(1496743200, 
1496779200, 1496793600, 1496808000, 1496829600, 1496851200, 1496869200, 
1496919600, 1496923200, 1496941200, 1496530800, 1496541600, 1496606400, 
1496617200, 1496649600, 1496696400, 1496808000, 1496844000, 1496876400, 
1496962800, 1497880800, 1497888000, 1497978000, 1497996000), class = c("POSIXct", 
"POSIXt"), tzone = ""), cnt = c(1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L 
)), .Names = c("source", "grp", "cnt"), row.names = c(NA, -24L 
), class = "data.frame") 
+0

관련 : [? 가장 빠른 방법은 data.frame 값을 누락 행을 추가하려면 (https://stackoverflow.com/questions/10438969/fastest-way-to-add-rows-for-missing 데이터 프레임 - 값/10473931 # 10473931) – Henrik

+0

@Henrik 링크를 가져 주셔서 감사합니다. 필자는 누락 된 날짜를 채우는 것에 대해 많은 질문을했지만 그 중 어떤 것에도 그룹화가 필요하지 않았습니다. – Sotos

+1

또한 [그룹별로 누락 날짜를 기입하십시오] (0120-333-2112) – Henrik

답변

3

그것은 data.table 정말 많은 tidyverse 옵션보다 빠른 것으로 보인다. 따라서 위의 내용을 data.table (@Frank의 칭찬)으로 번역하면 3 분 안에 작업이 완료됩니다.

library(data.table) 

mDT = setDT(d1)[, .(grp = seq(min(grp), max(grp), by = "hour")), by = source] 
new_D <- d1[mDT, on = names(mDT)] 

new_D <- new_D[, cnt := replace(cnt, is.na(cnt), 0)] #If needed 
1

동물원을 사용하여 수행 할 수도 있습니다. 이는 코드 및 데이터보다 훨씬 빠르지 만, data.table 솔루션만큼 빠르지는 않습니다.하지만 아래 코드의 마지막 줄을 필요로하지 않으면 더 빨리 처리 할 가능성이 있습니다.

우리는 동물원 객체 zd1을 읽어 각 소스에 대한 열을 갖는 다 변수 시계열을 제공합니다. 우리는 그런 다음 모든 시간을 갖는 제로 폭 시리즈와 병합하고 melt=TRUE 인수를 사용하여 데이터 프레임으로 다시 강화시켜 data.frame이라는 긴 형식을 얻습니다. 와이드 폼 다 변수 동물원 시리즈를 사용할 수있는 경우 마지막 줄을 건너 뛸 수 있습니다.

library(zoo) 

z <- read.zoo(d1, split = 1, index = 2) # wide form 
zz <- merge(z, zoo(, seq(start(z), end(z), "hour"))) # expand 
fortify(zz, melt = TRUE) # convert to long form data.frame 
+0

고맙습니다. 이것은 그것을 전파하는 좋은 아이디어입니다! 내 첫 번째 동물원 개체로 변환하고 거기에서 이동하지만 그룹화와 함께 거기에 갈 수 없었다 인정한다. – Sotos