【发布时间】:2019-09-05 17:57:05
【问题描述】:
我有以下 2 个数据框:
library(tidyverse)
library(RSQLite)
df1 <- data.frame(user_id=c("A","B","C"),
transaction_date=c("2019-01-01","2019-01-01","2019-01-01"))
df2 <- data.frame(user_id=c("C","D","E"),
transaction_date=c("2019-01-03","2019-01-03","2019-01-03"))
df1
df2
# user_id transaction_date
# <fct> <fct>
# A 2019-01-01
# B 2019-01-01
# C 2019-01-01
# user_id transaction_date
# <fct> <fct>
# C 2019-01-03
# D 2019-01-03
# E 2019-01-03
我想找出每个 user_id 的最短交易日期。我可以这样做:
rbind(df1, df2) %>%
group_by(user_id) %>%
summarise(min_dt=min(transaction_date %>% as.Date()))
# user_id min_dt
# <fct> <date>
# A 2019-01-01
# B 2019-01-01
# C 2019-01-01
# D 2019-01-03
# E 2019-01-03
问题是我有 100 个数据帧(每天 1 个)和每个数据帧数百万行。每次我引入新的 user_id 并计算 min_dt 时,user_id 的列表都会增长。因此,随着时间的推移,整个过程变得非常缓慢。 问题:1) 在 SQLite 中运行计算会更快吗? 2)如果是这样,我怎样才能在不每次都在本地下载数据的情况下做到这一点?
这是我尝试过的。
第 1 步:从 df1 创建数据库:
db <- dbConnect(SQLite(), dbname = "user_db.sqlite")
dbWriteTable(conn = db, name = "first_appeared", value = df1, append=TRUE)
tbl(db, "first_appeared")
## Source: table<first_appeared> [?? x 2]
## Database: sqlite 3.29.0 [user_db.sqlite]
# user_id transaction_date
# <chr> <chr>
# 1 A 2019-01-01
# 2 B 2019-01-01
# 3 C 2019-01-01
第 2 步:附加 df2:
dbWriteTable(conn = db, name = "first_appeared", value = df2, append=TRUE)
tbl(db, "first_appeared")
## Source: table<first_appeared> [?? x 2]
## Database: sqlite 3.29.0 [/Volumes/GoogleDrive/My Drive/Ad hoc/201908 v2
# mapper/user_db.sqlite]
# user_id transaction_date
# <chr> <chr>
# 1 A 2019-01-01
# 2 B 2019-01-01
# 3 C 2019-01-01
# 4 C 2019-01-03
# 5 D 2019-01-03
# 6 E 2019-01-03
第三步:在 SQLite 中计算 min_dt
tbl(db, "first_appeared") %>%
group_by(user_id) %>%
summarise(first_appeared=min(transaction_date))
dbDisconnect(db) # Close connection
## Source: lazy query [?? x 2]
## Database: sqlite 3.29.0 [/Volumes/GoogleDrive/My Drive/Ad hoc/201908 v2
## mapper/user_db.sqlite]
# user_id first_appeared
# <chr> <chr>
# 1 A 2019-01-01
# 2 B 2019-01-01
# 3 C 2019-01-01
# 4 D 2019-01-03
# 5 E 2019-01-03
第 4 步:如何在不先将数据下载到本地的情况下将这些结果直接传输到数据库(覆盖数据库)?
【问题讨论】: