首页 > 解决方案 > R中是否有一种方法可以创建一个变量,该变量是一个数据帧的变量之和,该变量以第一个数据帧中的变量为条件?

问题描述

您好,我是 R 和数据库的新手,我在加入两个数据库时遇到问题。

让我解释一下,我有两个数据库

第一个(称为 m)具有以下变量

实体代码 小时
a 3024 8:00
b 3024 8:05
c 2111 8:11
d 2111 8:18
e 2111 8:33
f 2111 8:50
g 2111 9:08

第二个称为 m2 具有以下变量

总小时数2
102 7:55
5000 7:58
500 8:00
600 8:10
800 8:30
50 8:45
100 8:55
80 9:05

我需要在数据库 m(变量 t)中创建一个变量,该变量等于数据库 m2 中 Total 列中元素的总和,此时该数据库中的 Hour2 将优于 Hour + 5 分钟并且将是低于小时 - 5 分钟。

例如

对于 m 中的实体 a,小时为 8:00
因此,当小时在 7:55 和 8:05 之间时,我想将 m2 中所有元素的总和,在示例中为 5602。

我希望我的结果是:

实体代码 小时 t
a 3024 8:00 5602
b 3024 8:05 1100
c 2111 8:11 600
d 2111 8:18 0
e 2111 8:33 800
f 2111 8:50 150
g 2111 9:08 80

我尝试了以下代码

m<-mutate(m, t=sum(select(m2[Hour+300 >= m2$Hour & Hour-300 
  <= m2$Hour,],Total)))<br><br>

但不工作它返回一个错误的值。

然后我决定用 for 语句编写代码:

for(i in 1:nrow(m)){
  Hour2<-m$Hour[i]
  m$t[i]<-sum(select(filter(m2,Hour>=Hour2-300, Hour<=Hour2+300),Total))  
}

代码运行良好买它太慢了:/,我需要多次运行代码,所以我正在寻找一种更好的方法来解决我的问题

标签: r

解决方案


我们可以使用fuzzyjoin按时间间隔加入

library(tidyverse)
library(fuzzyjoin)
fuzzy_full_join(
    m %>% mutate(
        Hour = as.POSIXct(Hour, format = "%H:%M"),
        Hour.min = Hour - as.difftime(5, unit = "mins"),
        Hour.max = Hour + as.difftime(5, unit = "mins")),
    m2 %>% mutate(Hour2 = as.POSIXct(Hour2, format = "%H:%M")),
    by = c("Hour.min" = "Hour2", "Hour.max" = "Hour2"),
    match_fun = list(`<=`, `>=`)) %>%
    select(-Hour.min, -Hour.max) %>%
    group_by(Entity, Code, Hour) %>%
    summarise(Total = sum(Total)) %>%
    mutate(Total = replace_na(Total, 0))
## A tibble: 7 x 4
## Groups:   Entity, Code [7]
#  Entity  Code Hour                Total
#  <fct>  <int> <dttm>              <dbl>
#1 a       3024 2019-02-16 08:00:00  5602
#2 b       3024 2019-02-16 08:05:00  1100
#3 c       2111 2019-02-16 08:11:00   600
#4 d       2111 2019-02-16 08:18:00     0
#5 e       2111 2019-02-16 08:33:00   800
#6 f       2111 2019-02-16 08:50:00   150
#7 g       2111 2019-02-16 09:08:00    80

解释:我们创建新的列Hour.maxHour.minas m$Hour± 5 分钟,然后执行一个fuzzy_full_join主题到m$Hour.min <= m2$Hour2and m$Hour.max >= m2$Hour2;最后一步是对TotalbyEntityCode的简单总结Hour


样本数据

m <- read.table(text =
    "Entity   Code   Hour
a      3024     8:00
b      3024     8:05
c      2111     8:11
d        2111     8:18
e      2111     8:33
f       2111     8:50
g      2111     9:08", header = T)

m2 <- read.table(text =
    "Total    Hour2
102     7:55
5000    7:58
500     8:00
600     8:10
800     8:30
50      8:45
100     8:55
80      9:05 ", header = T)

推荐阅读