【问题标题】:Averages by Time in RR中的时间平均值
【发布时间】:2018-04-12 05:10:50
【问题描述】:

我每秒测量一次化合物浓度。我想做 30 和 60 秒的平均值。我一直在阅读这里的帖子,我试过lubridatedplyr。但没有运气。我正在努力完成这项工作,但我无法做到。我正在从 SAS 过渡到 R,所以请耐心等待。

这是我的数据:

head (data)#show the first 6 rows

   Date     Time  Temp      Appb    Bppb    Cppb     Dppb    Eppb      Fppb

1 10/30/17 21:32:33 25.23 -0.469304 22.4445 35.5993 -18.4843 52.0488 -2.947340   
2 10/30/17 21:32:34 25.23 -1.255780 21.8248 34.2364 -20.9051 47.4344 -2.071230  
3 10/30/17 21:32:35 25.23 -0.769233 21.1590 30.5892 -20.9347 42.6061 -0.991607  
4 10/30/17 21:32:36 25.23 -0.874262 21.3353 25.4841 -19.6127 38.3224 -0.452383  
5 10/30/17 21:32:37 25.24 -0.819439 21.1916 21.4919 -16.5991 36.1331 -0.150002  
6 10/30/17 21:32:38 25.24 -1.895730 21.5345 18.0576 -17.2539 31.7448 -0.311064   

【问题讨论】:

    标签: r time average analysis seconds


    【解决方案1】:

    好吧,您可以执行以下操作:

    data$time_bucket <- 
      as.POSIXct(round(as.numeric(as.POSIXct(paste(data$Date, data$Time), format="%m/%d/%y %H:%M:%S"))/30)*30, origin='1970-01-01')
    

    这可能看起来有点复杂,但它执行以下操作:

    1. as.POSIXct(paste(data$Date, data$Time), format="%m/%d/%y %H:%M:%S") 将日期和时间列粘贴在一起以创建一个“日期时间”对象。
    2. as.numeric 将其转换为“纪元”数 - 自 1970-01-01 以来的秒数
    3. 除以 30,四舍五入并乘以 30 - 这将创建 30 秒的存储桶。舍入到相同数字的所有时间在舍入后将具有相同的“标签”。
    4. 最后使用as.POSIXct将其转换为“日期时间”。

    完成所有这些后,您可以按时间段取平均值,例如使用dplyr

    data %>% group_by(time_bucket) %>%
      summarize(mean(Temp))
    

    希望这能回答你的问题。

    【讨论】:

      【解决方案2】:

      这是来自xtsperiod.apply 的另一个解决方案:

      library(lubridate)
      library(xts)
      
      data_ts = as.xts(data[-c(1:2)], mdy_hms(paste(data$Date, data$Time)))
      
      ep = endpoints(data_ts, 'seconds', k = 30)
      
      period.apply(data_ts, ep, FUN = mean)
      

      结果:

                              Temp      Appb     Bppb     Cppb      Dppb    Eppb      Fppb
      2017-10-30 21:32:38 25.23333 -1.013958 21.58162 27.57642 -18.96497 41.3816 -1.153938
      

      由于您的所有样本数据都在 30 秒内,因此您只能获得每列的一个平均值。要验证我的答案是否确实有效,您可以尝试 2 秒的平均值:

      test_ep = endpoints(data_ts, 'seconds', k = 2)
      
      period.apply(data_ts, test_ep, FUN = mean)
      

      结果:

                            Temp       Appb     Bppb    Cppb     Dppb     Eppb       Fppb
      2017-10-30 21:32:33 25.230 -0.4693040 22.44450 35.5993 -18.4843 52.04880 -2.9473400
      2017-10-30 21:32:35 25.230 -1.0125065 21.49190 32.4128 -20.9199 45.02025 -1.5314185
      2017-10-30 21:32:37 25.235 -0.8468505 21.26345 23.4880 -18.1059 37.22775 -0.3011925
      2017-10-30 21:32:38 25.240 -1.8957300 21.53450 18.0576 -17.2539 31.74480 -0.3110640
      

      数据:

      data = read.table(text = "   Date     Time  Temp      Appb    Bppb    Cppb     Dppb    Eppb      Fppb
                        1 10/30/17 21:32:33 25.23 -0.469304 22.4445 35.5993 -18.4843 52.0488 -2.947340   
                        2 10/30/17 21:32:34 25.23 -1.255780 21.8248 34.2364 -20.9051 47.4344 -2.071230  
                        3 10/30/17 21:32:35 25.23 -0.769233 21.1590 30.5892 -20.9347 42.6061 -0.991607  
                        4 10/30/17 21:32:36 25.23 -0.874262 21.3353 25.4841 -19.6127 38.3224 -0.452383  
                        5 10/30/17 21:32:37 25.24 -0.819439 21.1916 21.4919 -16.5991 36.1331 -0.150002  
                        6 10/30/17 21:32:38 25.24 -1.895730 21.5345 18.0576 -17.2539 31.7448 -0.311064", 
                        header = TRUE, stringsAsFactors = FALSE)
      

      【讨论】:

      • 谢谢。我实际上让它工作,除了数据部分。我的数据集包含 6,500 行。我不明白我是否必须编写每个数据点。
      【解决方案3】:

      为了完整起见,这里有一个 data.tablelubridate 方法。

      library(data.table)
      library(lubridate)
      
      dat <- read.table(text = "Date     Time  Temp      Appb    Bppb    Cppb     Dppb    Eppb      Fppb
                                1 10/30/17 21:32:33 25.23 -0.469304 22.4445 35.5993 -18.4843 52.0488 -2.947340   
                                2 10/30/17 21:32:34 25.23 -1.255780 21.8248 34.2364 -20.9051 47.4344 -2.071230  
                                3 10/30/17 21:32:35 25.23 -0.769233 21.1590 30.5892 -20.9347 42.6061 -0.991607  
                                4 10/30/17 21:32:36 25.23 -0.874262 21.3353 25.4841 -19.6127 38.3224 -0.452383  
                                5 10/30/17 21:32:37 25.24 -0.819439 21.1916 21.4919 -16.5991 36.1331 -0.150002  
                                6 10/30/17 21:32:38 25.24 -1.895730 21.5345 18.0576 -17.2539 31.7448 -0.311064   ",
                        header = T, stringsAsFactors = F)
      
      #convert to R date object 
      dat$tme <- as.POSIXct(strptime(paste(dat$Date, dat$Time), format = "%m/%d/%y %H:%M:%S"), tz = "America/Montreal")
      
      #convert to data.table
      dat <- as.data.table(dat)
      
      #drop Date and Time since we have an R date object now
      dat <- dat[,-c(1,2)]
      
      #result
      dat[, lapply(.SD, mean), .(tme = round_date(tme, "3 seconds"))]
      

      我四舍五入到 3 秒,因为样本数据都在 30 秒内(与上面的答案相同)。

      结果如下:

          tme     Temp      Appb     Bppb     Cppb      Dppb     Eppb       Fppb
      1: 2017-10-30 21:32:33 25.23000 -0.862542 22.13465 34.91785 -19.69470 49.74160 -2.5092850
      2: 2017-10-30 21:32:36 25.23333 -0.820978 21.22863 25.85507 -19.04883 39.02053 -0.5313307
      3: 2017-10-30 21:32:39 25.24000 -1.895730 21.53450 18.05760 -17.25390 31.74480 -0.3110640
      

      我个人更喜欢 data.table 方法,尤其是对于较大的数据集,因为它的速度以及对子集和执行操作非常方便。

      【讨论】:

      • 当你输入 dat
      • 没关系。我正在使用您的示例数据,这就是它这样写的原因。根据数据格式,您可以将原始数据直接读入 R。例如,如果您有一个 .csv/.txt 文件,您可以使用 data.table 包中的 fread() ,这非常快。有来自 xlsx 包的 read_xlsx 用于 MS excel 文件。如果您的数据在线,您也可以通过 API 调用读取数据。
      • 谢谢。这是我一直在做的。 data
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-08
      • 1970-01-01
      • 2014-02-24
      相关资源
      最近更新 更多