R语言 通过包括时间在内的多个变量进行汇总

e5nszbig  于 2023-04-18  发布在  其他
关注(0)|答案(3)|浏览(86)

我是R语言编程的新手(就此而言,我根本不懂编程......),我正在为我的班级的一个项目做一些数据分析,我有一些数据,看起来像这样:
| 身份证|时间|心率|
| --------------|--------------|--------------|
| 1341231|2016-04-12 07:23:30|九十五|
| 1341231|2016年4月12日07时23分40秒|一百零一|
| 1341231|2016-04-12 07:23:50|九十二|
| 1341231|2016-04-12 07:24:00|八十七|
| 2342383|2016-04-12 07:23:30|六十|
这是来自可穿戴健身追踪器的数据,以5秒或10秒为间隔。这是一个相当大的数据集,有超过200万个条目。我想做的是:对于每个ID(也就是每个用户),按小时汇总秒数数据,返回每个小时的平均心率。因此,我希望输出如下所示:
| 身份证|时间|心率|
| --------------|--------------|--------------|
| 1341231|2016-04-12 07:00|九十五|
| 1341231|2016-04-12 08:00|八十二|
| 1341231|2016-04-12 09:00|八十|
| 1341231|2016-04-12 10:00|一百|
| 2342383|2016-04-12 07:00|六十五|
日期最初是字符串,所以我用lubridate.解析它们,但在那之后,事情开始出错。
所以,我转向我最好的技术:复制粘贴不完全理解的代码。
首先,我尝试test_df <- aggregate(Heartrate ~ format(as.POSIXct(sechr$Time), "%m-%d-%y %H"), data=sechr, mean)
但这并不好。正如我很快意识到的那样,这完全放弃了Id,以一种或多或少无用的方式总结了我的数据。
所以,接下来我尝试了aggregate的各种公式,它似乎没有为另一个变量采取另一个参数,然后用summarizegroup_by进行实验,如下所示:
testdf3 <- sechr %>% group_by(c(Time ~ format(as.POSIXct(sechr$Time))), "%m-%d-%y %H", Id) %>% summarise(avg_hr=sum(Heartrate))
不用说,基本上猜测根本不起作用。我产生了很多错误和几个愚蠢的、无用的 Dataframe 。
基本上,我需要的是一种方法来说“对于每个不同的ID,给予我每个小时的平均值。”我认为使用xts是一种方法?也许吧?但是我对如何做我想做的事情感到困惑。

qlfbtfca

qlfbtfca1#

这是使用{data.table}的一个相当临时的解决方案。
我复制了前几行来测试它。

sechr <- data.table(Id = c("1341231", "1341231", "1341231", "1341231", "2342383"),
                    Time = c("2016-04-12 07:23:30", "2016-04-12 07:23:40",
                             "2016-04-12 07:23:50", "2016-04-12 07:24:00",
                             "2016-04-12 07:23:30"),
                    Heartrate = c(95, 101, 92, 87, 60))

在这里,我通过引用第一次出现冒号之前的数字(当然还有日期)来确定小时。

sechr[, TimeH := gsub(":.*", ":00:00", Time)]
sechr_ByIDHour <- sechr[, .(Heartrate = mean(Heartrate)), .(Id, TimeH)]
xxslljrj

xxslljrj2#

一种使用我的timeplyr包的方法。顾名思义,它是对dplyr的时间扩展,因此可以自然地使用tidyverse语法。

# remotes::install_github("NicChr/timeplyr")
library(timeplyr)
library(dplyr)
library(lubridate)
sechr %>%
  mutate(Time = ymd_hms(Time)) %>%
  group_by(Id) %>%
  time_summarise(avg_hr = mean(Heartrate), 
                 time = Time, by = "hour")
#> # A tibble: 2 x 3
#> # Groups:   Id [2]
#>        Id Time                avg_hr
#>     <int> <dttm>               <dbl>
#> 1 1341231 2016-04-12 07:23:30   93.8
#> 2 2342383 2016-04-12 07:23:30   60

创建于2023-04-14带有reprex v2.0.2
time_summarise()更灵活,因为您可以按任何时间单位聚合。

sechr2 <- sechr %>%
  mutate(Time = ymd_hms(Time)) %>%
  group_by(Id)
sechr2 %>%
  time_summarise(avg_hr = mean(Heartrate), 
                 time = Time, by = "30 seconds")
#> # A tibble: 3 x 3
#> # Groups:   Id [2]
#>        Id Time                avg_hr
#>     <int> <dttm>               <dbl>
#> 1 1341231 2016-04-12 07:23:30     96
#> 2 1341231 2016-04-12 07:24:00     87
#> 3 2342383 2016-04-12 07:23:30     60
sechr2 %>%
  time_summarise(avg_hr = mean(Heartrate), 
                 time = Time, by = "minute")
#> # A tibble: 2 x 3
#> # Groups:   Id [2]
#>        Id Time                avg_hr
#>     <int> <dttm>               <dbl>
#> 1 1341231 2016-04-12 07:23:30   93.8
#> 2 2342383 2016-04-12 07:23:30   60
sechr2 %>%
  time_summarise(avg_hr = mean(Heartrate), 
                 time = Time, by = "30 minutes")
#> # A tibble: 2 x 3
#> # Groups:   Id [2]
#>        Id Time                avg_hr
#>     <int> <dttm>               <dbl>
#> 1 1341231 2016-04-12 07:23:30   93.8
#> 2 2342383 2016-04-12 07:23:30   60

如果由于某种原因您没有特定时间间隔的数据,您也可以在时间上完成缺失的间隙。

sechr2 %>%
  time_complete(time = Time, to = min(Time) + years(1))
#> Assuming a time granularity of 10 seconds
#> # A tibble: 6,307,202 x 3
#> # Groups:   Id [2]
#>         Id Time                Heartrate
#>  *   <int> <dttm>                  <int>
#>  1 1341231 2016-04-12 07:23:30        95
#>  2 1341231 2016-04-12 07:23:40       101
#>  3 1341231 2016-04-12 07:23:50        92
#>  4 1341231 2016-04-12 07:24:00        87
#>  5 1341231 2016-04-12 07:24:10        NA
#>  6 1341231 2016-04-12 07:24:20        NA
#>  7 1341231 2016-04-12 07:24:30        NA
#>  8 1341231 2016-04-12 07:24:40        NA
#>  9 1341231 2016-04-12 07:24:50        NA
#> 10 1341231 2016-04-12 07:25:00        NA
#> # ... with 6,307,192 more rows
svmlkihl

svmlkihl3#

你的group_by() %>% summarize()尝试并没有 * 太 * 远;我对它进行了一些清理,并使用lubridate::tz()format()中指定了时区。

library(dplyr)
library(lubridate)

sechr %>% 
  group_by(Id, Time = format(Time, "%m-%d-%y %H", tz = tz(Time))) %>%
  summarise(avg_hr = mean(Heartrate)) %>%
  ungroup()
# A tibble: 2 × 3
       Id Time        avg_hr
    <dbl> <chr>        <dbl>
1 1341231 04-12-16 07   93.8
2 2342383 04-12-16 07   60

如果您希望将Time作为datetime对象,那么format()的另一种选择是使用lubridate::floor_date()向下舍入到小时。

sechr %>% 
  group_by(Id, Time = floor_date(Time, "hour")) %>%
  summarise(avg_hr = mean(Heartrate)) %>%
  ungroup()
# A tibble: 2 × 3
       Id Time                avg_hr
    <dbl> <dttm>               <dbl>
1 1341231 2016-04-12 07:00:00   93.8
2 2342383 2016-04-12 07:00:00   60

相关问题