2016-06-17 1 views
2

센서 (1 ~ 16)에서 측정을 수행 한 데이터 세트가 있는데,이 데이터 세트는 반복 횟수만큼 반복됩니다. 각 시퀀스의 각 센서에 대해 value의 평균을 원합니다. 모든 시퀀스가 ​​16에서 1로 되돌아가는 것은 아닙니다 (때로는 제거해야 할 표유 측정 값이 있습니다). 참고 : 이것은 작고 가짜 데이터 집합입니다.그룹화가 필요한 데이터 집합에서 집계를 계산하는 방법은 무엇입니까?

dataset (또한 아래의 스크립트를 읽을 수 있습니다)

# To read with rio 
# library("devtools") 
# install_github("leeper/rio") 
library("rio") 
df <- import("https://gist.githubusercontent.com/karthik/ad2874e5b5c5f3af73ad89d14b26a913/raw/f435317539bc56a09b248a0ef193db21b7176eee/small.csv") 

내 첫 번째 시도 : 지금은 쉽게된다

library(dplyr) 
# Assigning groups to the data 
df$diff <- c(df$sensor[2:nrow(df)], 0) - df$sensor 
# There is sometimes a sensor reading between 16 and 1. This removes those rows. 
df2 <- df[-which(df$diff < 0 & df$sensor != 16),] 

# end is now where the last 16 was 
end <- which(df2$diff < 0) 
# Start begins with 1, then adds 1 to the position of every last 16 sensor 
# reading to get the next 1 
start <- 
    c(1, which(df2$diff < 0)[1:length(which(df2$diff < 0)) - 1] + 1) 
# Now combine both into a data.frame 
positions <- data_frame(start, end) 
# Add unique groups 
positions$group <- 1:nrow(positions) 
df2$group <- NA 

# Yes this is a horrible loop and 
# super inefficient on the full dataset. 
for (i in 1:nrow(positions)) { 
    df2[positions[i,]$start:positions[i, ]$end, ]$group <- 
    positions[i,]$group 
} 

함께 집계를 할 dplyr

df3 <- df2 %>% 
    group_by(sensor,group) %>% 
    summarise(mean_value = mean(value)) 
    head(df3) 

내가 원하는 결과.

Source: local data frame [6 x 3] 
    Groups: sensor [4] 

    sensor group mean_value 
    (int) (int)  (dbl) 
    1  1  2 0.07285933 
    2  2  2 0.06993007 
    3  3  1 0.04845651 
    4  3  2 0.03976837 
    5  4  1 0.06033732 
    6  4  2 0.06480888 

더 좋은 방법은 무엇입니까?

답변

3

positions 데이터 프레임을 만들고 중간 데이터 프레임 df2을 만들고 for 루프를 사용하여 그룹화 변수를 추가하는 대신 dplyr 어휘로 모든 작업을 수행 할 수 있습니다. cumsumlag의 조합을 사용하면 mutate과 함께 그룹화 변수를 추가 할 수 있습니다. 후자는 기능도 있기 때문에 내가 대신 diff의 변수 이름으로 differ을 사용 (그리고 그것은되지 않습니다 :

df %>% 
    mutate(differ = lead(sensor) - sensor) %>% 
    filter(!(differ < 0 & sensor != 16)) %>% 
    mutate(grp = cumsum(lag(differ,default=0) < 0) + 1) %>% 
    group_by(sensor, grp) %>% 
    summarise(mean_val = mean(value)) 

제공 :

Source: local data frame [30 x 3] 
Groups: sensor [?] 

    sensor grp mean_val 
    (int) (dbl)  (dbl) 
1  1  2 0.07285933 
2  2  2 0.06993007 
3  3  1 0.04845651 
4  3  2 0.03976837 
5  4  1 0.06033732 
6  4  2 0.06480888 
7  5  1 0.03276722 
8  5  2 0.05005240 
9  6  1 0.06967405 
10  6  2 0.06484712 
.. ... ...  ... 

참고이 훨씬 더 단순화 된 절차의 결과 칼럼에 'funcion'-name을 주면 현명합니다.)


당신은이에 대한 data.table 패키지를 사용할 수 있습니다

library(data.table) 
setDT(df)[, differ := shift(sensor, type='lead') - sensor 
      ][!(differ < 0 & sensor != 16) 
      ][, grp := cumsum(shift(differ,fill=0) < 0) + 1 
       ][, .(mean_val = mean(value)), .(sensor,grp)] 

하는 setDT(df)는 데이터 테이블로 dataframe를 변환합니다.

관련 문제