如何过滤数据集和R中计算出一个新的变量快?

问题描述 投票:2回答:4

我有一个值每分钟的数据集,我想计算每个小时的平均值。我已经通过使用GROUP_BY(),过滤器()尝试和总结()从dplyr封装,以减少每个小时的数据。当我只使用这些功能,我能够得到的平均值为每一个小时,但只有每个月,我希望它的每一天。

> head(DF)
         datetime        pw        cu          year m  d hr min
1 2017-08-18 14:56:00 0.0630341 1.94065        2017 8 18 14  53
2 2017-08-18 14:57:00 0.0604653 1.86771        2017 8 18 14  57
3 2017-08-18 14:58:00 0.0601318 1.86596        2017 8 18 14  58
4 2017-08-18 14:59:00 0.0599276 1.83761        2017 8 18 14  59
5 2017-08-18 15:00:00 0.0598998 1.84177        2017 8 18 15   0

我不得不使用一个for循环来减少我的表,我写了下面这样做:

datetime <- c()
eg_bf <-c ()

for(i in 1:8760){  
    hour= start + 3600

    DF= DF %>% 
      filter(datetime >= start & datetime < hour) %>% 
      summarise(eg= mean(pw))

    datetime= append(datetime, start)
    eg_bf= append(eg_bf, DF$eg)

    start= hour
    }
new_DF= data.frame(datetime, eg_bf)

所以。我能得到我的新数据与当年的每小时平均值设定。

  datetime             eg_bf
1 2018-01-01 00:00:00  0.025
2 2018-01-01 01:00:00  0.003
3 2018-01-01 02:00:00  0.002
4 2018-01-01 03:00:00  0.010
5 2018-01-01 04:00:00  0.015

我现在面临的问题是,它需要大量的时间来做到这一点。我们的想法是这样计算添加到一个闪亮的UI,所以每次我做出改变,必须做出改变得更快。任何想法如何提高这个计算?

r for-loop dplyr
4个回答
2
投票

你可以试试这个。使用make_date从lubridate包使用的数据集的年,月,日,时列作新DATE_TIME列。然后组和新列总结

library(dplyr)
library(lubridate)
 df %>% 
   mutate(date_time = make_datetime(year, m, d, hr)) %>%  
   group_by(date_time) %>% 
   summarise(eg_bf = mean(pw))

2
投票

@Adam Gruer的回答为那些应该解决你的问题的日期变量一个很好的解决方案。每小时平均的计算时只用dplyr工作,虽然:

df %>%
  group_by(year, m, d, hr) %>%
  summarise(test = mean(pw))

# A tibble: 2 x 5
# Groups:   year, m, d [?]
   year     m     d    hr   test
  <int> <int> <int> <int>  <dbl>
1  2017     8    18    14 0.0609
2  2017     8    18    15 0.0599

你在你的问题说:

当我只使用这些功能,我能够得到的平均值为每一个小时,但只有每个月,我希望它的每一天。

你做了什么不同?


1
投票

即使你发现你的答案,我相信这是值得一提:

如果你有大量的数据工作,速度是一个问题,那么你可能想OT看看你是否可以改用data.tabledplyr

你可以用一个简单的标杆看到更快data.table如何:

library(dplyr)
library(lubridate)
library(data.table)
library(microbenchmark)
set.seed(123)

# dummy data, one year, one entry per minute
# first as data frame
DF <- data.frame(datetime = seq(as.POSIXct("2018-01-01 00:00:00"), 
                                as.POSIXct("2019-01-02 00:00:00"), 60),
                 pw = runif(527041)) %>% 
  mutate(year = year(datetime), m=month(datetime), 
         d=day(datetime), hour = hour(datetime))

# save it as a data.table
dt <- as.data.table(DF)

# transformation with dplyr
f_dplyr <- function(){
  DF %>% 
    group_by(year, m, d, hour) %>% 
    summarize(eg_bf = mean(pw))
}


# transformation with data.table
f_datatable <- function() {
  dt[, mean(pw), by=.(year, m, d, hour)]
}

# benchmarking
microbenchmark(f_dplyr(), f_datatable())

# 
# Unit: milliseconds
#          expr       min        lq     mean   median       uq      max neval cld
#     f_dplyr() 41.240235 44.075019 46.85497 45.64998 47.95968 76.73714   100   b
# f_datatable()  9.081295  9.712694 12.53998 10.55697 11.33933 41.85217   100  a

看看这个职位它道出了很多data.table vs dplyr: can one do something well the other can't or does poorly?


0
投票

我了解你的365个* 24个* 60行的数据帧。下面的代码立即返回结果。结果是平均值(PW)在今年的每小时分组。


remove(list = ls())

library(dplyr)
library(lubridate)
library(purrr)
library(tibble)

date_time <- seq.POSIXt(
    as.POSIXct("2018-01-01"),
    as.POSIXct("2019-01-01"),
    by = "1 min"
)

n <- length(date_time)

data <- tibble(
    date_time = date_time,
    pw = runif(n),
    cu = runif(n),
    ye = year(date_time),
    mo = month(date_time),
    da = day(date_time),
    hr = hour(date_time)
)

grouped <- data %>% 
    group_by(
        ye, mo, da, hr
    ) %>% 
    summarise(
        mean_pw = mean(pw)
    )


© www.soinside.com 2019 - 2024. All rights reserved.