【问题标题】:When does dplyr's mutate function work with a database?dplyr 的 mutate 函数何时与数据库一起使用?
【发布时间】:2016-12-12 14:21:09
【问题描述】:

我尝试在类似 SQL 的数据库上使用 dplyrmutate() 函数。我不明白为什么它有时有效而其他时候无效。

这是一个来自https://cran.rstudio.com/web/packages/dplyr/vignettes/databases.html的标准示例

将数据加载到数据库中

> library(nycflights13)
> library(dplyr)
> db_sqlite <- src_sqlite("data/my_db.sqlite3", create = TRUE)
> flights_sqlite <- copy_to(db_sqlite, flights, temporary = FALSE, indexes = list(
+   c("year", "month", "day"), "carrier", "tailnum"))

成功创建新数值变量

如果我尝试创建一个新的数值变量,例如 year2,一切正常

> tbl(db_sqlite, "flights") %>% mutate(year2 = year + 10)
Source:   query [?? x 20]
Database: sqlite 3.8.6 [data/my_db.sqlite3]

    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay carrier flight
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>     <dbl>   <chr>  <int>
1   2013     1     1      517            515         2      830            819        11      UA   1545
2   2013     1     1      533            529         4      850            830        20      UA   1714
3   2013     1     1      542            540         2      923            850        33      AA   1141
4   2013     1     1      544            545        -1     1004           1022       -18      B6    725
5   2013     1     1      554            600        -6      812            837       -25      DL    461
6   2013     1     1      554            558        -4      740            728        12      UA   1696
7   2013     1     1      555            600        -5      913            854        19      B6    507
8   2013     1     1      557            600        -3      709            723       -14      EV   5708
9   2013     1     1      557            600        -3      838            846        -8      B6     79
10  2013     1     1      558            600        -2      753            745         8      AA    301
# ... with more rows, and 9 more variables: tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>,
#   distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dbl>, year2 <dbl>

但未能使用paste0() 创建新的字符变量

如果我尝试使用基本函数 paste0() 创建一个新变量,我会遇到错误。

> tbl(db_sqlite, "flights") %>% mutate(date = paste0(year, month, day))
Source:   query [?? x 20]
Database: sqlite 3.8.6 [data/my_db.sqlite3]

Error in sqliteSendQuery(conn, statement) : 
  error in statement: no such function: PASTE0

会话信息在这里:

> devtools::session_info()
Session info ------------------------------------------------------------------------------------------------
 setting  value                       
 version  R version 3.3.2 (2016-10-31)
 system   x86_64, linux-gnu           
 ui       RStudio (1.0.35)            
 language (EN)                        
 collate  C                           
 tz       <NA>                        
 date     2016-12-12                  

Packages ----------------------------------------------------------------------------------------------------
 package      * version    date       source                          
 DBI            0.5-1      2016-09-10 cran (@0.5-1)                   
 R6             2.2.0      2016-10-05 cran (@2.2.0)                   
 RSQLite        1.0.0      2014-10-25 CRAN (R 3.2.2)                  
 Rcpp           0.12.8     2016-11-17 cran (@0.12.8)                  
 assertthat     0.1        2013-12-06 CRAN (R 3.2.2)                  
 devtools       1.12.0     2016-06-24 CRAN (R 3.3.1)                  
 digest         0.6.10     2016-08-02 CRAN (R 3.2.3)                  
 dplyr        * 0.5.0.9000 2016-12-12 Github (hadley/dplyr@c846cb3)   
 lazyeval       0.2.0.9000 2016-10-14 Github (hadley/lazyeval@c155c3d)
 magrittr       1.5        2014-11-22 CRAN (R 3.2.3)                  
 memoise        1.0.0      2016-01-29 CRAN (R 3.2.3)                  
 nycflights13 * 0.2.0      2016-04-30 CRAN (R 3.3.2)                  
 tibble         1.2        2016-08-26 CRAN (R 3.2.3)                  
 withr          1.0.2      2016-06-20 CRAN (R 3.2.3)               

在数据库上使用mutate() 可以进行哪些操作?

有没有办法在数据库上使用paste0()等函数而不将数据收集到内存中?

【问题讨论】:

  • dplyr 将一些函数转换为 SQL,或者,如果函数不存在,则将 函数名 传递给 SQL。您可以改为执行tbl(db_sqlite, "flights") %&gt;% mutate(date = sql("year||month||day")) 之类的操作。

标签: r dplyr rsqlite tidyverse


【解决方案1】:

好的,感谢@michael-griffiths 的评论,答案是:不能保证 R 函数可以翻译成 sql 代码。

所以,如果它返回错误,我们可以尝试使用 sql() 函数直接编写 sql 代码。

请注意,这取决于数据库(sqlite、postgre、mysql 或 mariadb 等)。

【讨论】:

    【解决方案2】:

    我认为这就是 collect() 方法的用途

    tbl(db_sqlite, "flights") %>% collect() %>% mutate(date = paste0(year, month, day))

    collect() 将数据检索到本地 tibble 中,然后您可以对其应用 R 函数。

    上面的代码我没有执行

    【讨论】:

      【解决方案3】:

      是的,那是因为paste0 在 SQLite 中没有对应的翻译。在dbplyr 中,我们通常可以使用CONCATENATE SQL 命令来等同于paste0 所做的操作。此命令应适用于不同的 SQL 后端。其他不适用于 SQLite,但可以用于其他数据库的命令,例如 min()max()

      关于评估,当您将dplyr 代码等同于一个变量时,即:db_var &lt;- db_table %&gt;% mutate(x = x +1) 将不会被评估,直到您对它执行某些操作,例如请求打印结果,这是通过传递 db_var 来完成的或在其末尾传递collect() 命令。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-11-21
        • 1970-01-01
        • 2023-02-15
        • 2019-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多