2017-08-12 106 views
0

我有這樣的數據集,它記錄在30分鐘步:R - 將30分鐘的數據幀聚合爲小時數據幀?

structure(list(Particles = c(0.596667, 0.27, 0.153333, 0, 0.753333, 
    0, 0.35, 0.506667, 1.6, 0.116667), PM = c(35.5158928571429, 16.0714285714286, 
    9.12696428571429, 0, 44.84125, 0, 20.8333333333333, 30.15875, 
    95.2380952380953, 6.94446428571429), timestamp = c(1493310389147, 
    1493310419191, 1493310449254, 1493310479270, 1493310509313, 1493310539387, 
    1493310569416, 1493310599465, 1493310629525, 1502378711339), 
     date = structure(c(1493310389.147, 1493310419.191, 1493310449.254, 
     1493310479.27, 1493310509.313, 1493310539.387, 1493310569.416, 
     1493310599.465, 1493310629.525, 1502378711.339), class = c("POSIXct", 
     "POSIXt"), tzone = "UTC-1"), site = c("ABC", "ABC", 
     "ABC", "ABC", "ABC", "ABC", 
     "ABC", "ABC", "ABC", "ABC" 
     ), code = c("ABC", "ABC", "ABC", 
     "ABC", "ABC", "ABC", "ABC", 
     "ABC", "ABC", "ABC"), key_date = c("2017-04-27", 
     "2017-04-27", "2017-04-27", "2017-04-27", "2017-04-27", "2017-04-27", 
     "2017-04-27", "2017-04-27", "2017-04-27", "2017-08-10")), .Names = c("Particles", 
    "PM", "timestamp", "date", "site", "code", "key_date"), row.names = c(NA, 
    10L), class = "data.frame") 

我怎麼能它聚集到每小時一步?我的列從一個數據框到另一個數據框有所不同,所以我需要一種聚合它的方式,以便它也可以應用於其他數據框。

編輯:

我試了一下:

res <- aggregate(Df['PM'], list(date = cut(as.POSIXct(Df$date), "1 hour")), sum) 

但這只是給我留下兩列,其餘的都沒有了。我怎樣才能保持他們呢?

+1

如何使用'cut'即'DF1 %>%group_by(小時=剪切(日期,休息=「小時」))%>%彙總(PM =總計(PM))' – akrun

+0

@akrun我該怎麼做?我得到這個錯誤'警告:%>%中的錯誤:找不到函數「%>%」' – laukok

+1

我假設你有'library(dplyr); df1%>%group_by(..' – akrun

回答

2

我們可以使用cut創造了每小時分組變量,然後summarise

library(dplyr) 
df1 %>% 
    group_by(Hour = cut(date, breaks = "hour")) %>% 
    summarise(PM = sum(PM)) 

我們也可以創建一個函數來傳遞分組列與列是summarise

fSumm <- function(dat, dateVar, groupVars, colstoSumm){ 
     dat %>% 
      group_by(Hour = cut(!! rlang::sym(dateVar), breaks = "hour")) %>% 
      group_by(!!! rlang::syms(groupVars), add = TRUE) %>% 
      summarise_at(vars(colstoSumm), sum) 
    } 

groups <- c("site", "code") 
cols <- c("Particles", "PM") 
dateV <- "date" 
fSumm(df1, dateV, groups, cols) 

我們也可以使用quo路線

fSumm <- function(dat, dateVar, groupVars, colstoSumm){ 
    cols <- sapply(colstoSumm, quo_name) 

    dat %>% 
     group_by(Hour = cut(!! dateVar, breaks = "hour")) %>% 
     group_by(!!! groupVars, add = TRUE) %>% 
     summarise_at(vars(cols), sum) 
} 

fSumm(df1, quo(date), quos(site, code), quos(Particles, PM)) 
+0

對不起,我檢查了它的數據實際上沒有任何區別... – laukok

+0

@teelou你需要將輸出分配給一個對象,即'res <- df1 %>%group_by ...'如果這需要原始數據集中的一列,那麼'df1 <- df1 %>%group_by(....)%>%mutate(PMSum = sum(PM))' – akrun

+0

明白了。只給了我兩列PM和Hour,剩下的列都沒有了,我怎麼能保留它們? – laukok

1

我們可以嘗試:

library(data.table) 
setDT(df) 
varsToSum <- c("PM", "Particles") 
df[, lapply(.SD[, ..varsToSum], sum), by = format(date, "%Y-%m-%d-%H")] 

      format   PM Particles 
1: 2017-04-27-17 251.785714 4.230000 
2: 2017-08-10-16 6.944464 0.116667 

,我們可以很容易地擴展到包括剩餘變量的第一個值:

cbind(
    df[, lapply(.SD[, ..varsToSum], sum), by = format(date, "%Y-%m-%d-%H")] 
    , df[, lapply(.SD[, !(names(df) %in% varsToSum), with = FALSE], head, 1), 
    by = format(date, "%Y-%m-%d-%H")][, -"format"] 
) 

      format   PM Particles timestamp site code key_date 
1: 2017-04-27-17 251.785714 4.230000 1.493310e+12 ABC ABC 2017-04-27 
2: 2017-08-10-16 6.944464 0.116667 1.502379e+12 ABC ABC 2017-08-10