2

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

这是来自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()在不将数据收集到内存的情况下使用数据库等功能?

4

3 回答 3

1

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

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

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

于 2016-12-14T15:13:34.140 回答
0

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

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

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

我没有执行上面的代码

于 2017-05-01T15:23:44.990 回答
0

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

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

于 2018-04-13T23:55:07.213 回答