R data.table平均值,如果使用联接查找

时间:2019-04-16 11:27:05

标签: r data.table rmysql

我所要做的只是一个简单的均值if(就像在excel中的命令均值一样)。我正在使用data.tables来提高效率,因为我有相当大的表(〜1m行)。

我的目的是查找

Table 1 
| individual id | date        |
-------------------------------
| 1             |  2018-01-02 |
| 1             |  2018-01-03 |
| 2             |  2018-01-02 |
| 2             |  2018-01-03 |

Table 2 
| individual id | date2       | alpha |
---------------------------------------
| 1             |  2018-01-02 |  1    |  
| 1             |  2018-01-04 |  1.5  |
| 1             |  2018-01-05 |  1    |
| 2             |  2018-01-01 |  2    |  
| 2             |  2018-01-02 |  1    |
| 2             |  2018-01-05 |  4    |

目标结果

Updated table 1
| individual id | date        | mean(alpha) |
---------------------------------------------
| 1             |  2018-01-02 |  1          |
| 1             |  2018-01-03 |  1          |
| 2             |  2018-01-02 | 1.5         |
| 2             |  2018-01-03 | 1.5         |

这只是表2中此个人的所有值的平均值,该值在日期(包括日期)之前(日期2)发生。 结果可以由以下mysql命令产生,但我无法在R中再现它。

update table1
            set daily_alpha_avg = 
      (select avg(case when date2<date then alpha else 0 end) 
      from table2
      where table2.individual_id= table1.individual_id
      group by individual_id);

到目前为止,我最好的猜测是:

table1[table2, on = .(individual_id, date>=date2), 
          .(x.individual_id, x.date, bb = mean(alpha)), by= .(x.date, x.individual_id)]

table1[, daily_alpha_avg := table2[table1, mean(alpha), on =.(individual_id, date>=date2)]]

但是这是行不通的,我知道它是错误的,我只是不知道如何解决它。

感谢您的帮助

3 个答案:

答案 0 :(得分:4)

使用by = .EACHI,您可以执行以下操作:

table2[table1, 
       on = .(`individual id`), 
       .(date = i.date, mean_alpha = mean(alpha[date2 <= i.date])),
       by = .EACHI]

#    individual id       date mean_alpha
# 1:             1 2018-01-02        1.0
# 2:             1 2018-01-03        1.0
# 3:             2 2018-01-02        1.5
# 4:             2 2018-01-03        1.5

编辑:

# Assign by reference as a new column
table1[, mean_alpha := table2[table1, 
                              on = .(`individual id`), 
                              mean(alpha[date2 <= i.date]),
                              by = .EACHI][["V1"]]]

编辑2

这是弗兰克在评论部分建议的更优雅的方式。

# In this solution our date columns can't be type character
table1[, date := as.Date(date)]
table2[, date2 := as.Date(date2)]

table1[, mean_alpha := table2[table1, # or equivalently .SD instead of table1
                              on = .(`individual id`, date2 <= date), 
                              mean(alpha), 
                              by = .EACHI][["V1"]]]

可复制数据

table1 <- fread(
  "individual id | date       
   1             |  2018-01-02
   1             |  2018-01-03
   2             |  2018-01-02
   2             |  2018-01-03", 
  sep ="|"
)
table2 <- fread(
  "individual id | date2       | alpha
   1             |  2018-01-02 |  1     
   1             |  2018-01-04 |  1.5 
   1             |  2018-01-05 |  1   
   2             |  2018-01-01 |  2     
   2             |  2018-01-02 |  1   
   2             |  2018-01-05 |  4",
  sep = "|"
)

答案 1 :(得分:1)

tidyverse表演对您来说还不够吗?

我无法仅使用date2

#Please provide 

table1 <- tribble(~individual_id,~date,
                  1,"2018-01-02",
                  1,"2018-01-03",
                  2,"2018-01-02",
                  2,"2018-01-03")

table2 <- tribble(~individual_id,~date2,~alpha,
                  1,"2018-01-02",1,
                  1,"2018-01-04",1.5,
                  1,"2018-01-05",1,
                  2,"2018-01-01",2,
                  2,"2018-01-02",1,
                  2,"2018-01-05",4)

df <- left_join(table1,table2) %>%
  mutate(date = as.Date(date),
         date2 = as.Date(date2))

df %>% 
  group_by(individual_id,date) %>% 
  mutate(case = ifelse(date2<=date,alpha,NA)) %>% 
  summarise(mean_alpha = mean(case,na.rm = TRUE))

您还可以选择使用tidyverse生成sql查询,并且有sql_translations,签出https://dbplyr.tidyverse.org/articles/sql-translation.html并使用show_query函数来确保在sql和R之间使用相同的逻辑

答案 2 :(得分:0)

只需使用 sqldf 包,然后将您的查询放入 sqldf()

library(sqldf)
sqldf("your SQL goes here")
table1

就这样