如何使用dplyr将类tbl_mysql的对象转换为tbl_df?

时间:2016-04-16 21:48:40

标签: r dplyr

我使用以下代码下载mysql表并将其分配给对象nycflights

library(dplyr)    
my_db <- src_mysql(dbname = "dplyr",
                       host = "dplyr.csrrinzqubik.us-east-1.rds.amazonaws.com",
                       port = 3306,
                       user = "dplyr",
                       password = "dplyr")
    nycflights <- tbl(my_db, "dplyr")

然后,我想在使用dplyr进行计算之前在类tbl_df的数据帧中转换此对象。原因是有一些函数不能与类tbl_mysql的表一起使用。例如

> nycflights %>%
 sample_n(1)
Error: Don't know how to sample from objects of class tbl_mysql

原因是mysql数据库中的记录没有内在的顺序,因此不能随机采样。

回到我的问题,我尝试了3种不同的方法:

首先:

> tbl_df(nycflights)
Error: data is not a data frame

第二

> as_data_frame(nycflights)
Error: data_frames can only contain 1d atomic vectors and lists

第三,这太慢了,一段时间后崩溃了:

tbl_dt(nycflights)

更新

我问过的问题可能是实用性很低。在极少数情况下,用户需要collect()整个数据集。另外,要在tbl_mysql对象上获取随机样本,我可以使用以下代码:

nycflights %>% 
  mutate(x=rand()) %>% 
  collapse() %>% 
  filter(x<=.0001) %>% 
  select(-x) %>% 
  collect()

请记住rand()是一个真正的mysql函数。这一点让我很困惑,因为我按照r studio seminar

的建议使用了random()

2 个答案:

答案 0 :(得分:2)

您可以将collect()用于此目的。来自帮助:

  

collect也强制计算,但会将数据带回R data.frame(存储在tbl_df中)。

运行需要一些时间,但我认为这是正常的,因为数据集的大小:

system.time(nycflights_local <- collect(nycflights))
##    user  system elapsed 
##   1.177   0.404  17.839 
class(nycflights_local)
## [1] "tbl_df"     "tbl"        "data.frame"

如果您希望拥有tbl_dt,则可以轻松转换:

nycflights_dt <- tbl_dt(collect(nycflights))
class(nycflights_dt)
## [1] "tbl_dt"     "tbl"        "data.table" "data.frame"

与OP相反,我也可以直接在tbl_df()上使用nycflights,但生成的tbl_df对象会被裁剪为前100'000行:

nycflights_dt2 <- tbl_dt(nycflights)
## Warning message:
## Only first 100,000 results retrieved. Use n = -1 to retrieve all.

使用nycflights_local,您可以使用sample_n()

sample_n(nycflights_local, 5) %>% select(id:day)
## Source: local data frame [5 x 4]
## 
##       id  year month   day
##    (int) (int) (int) (int)
## 1  89847  2013    12     8
## 2  18669  2013     1    22
## 3  70178  2013    11    16
## 4 219012  2013     5    28
## 5 144250  2013     3     9

答案 1 :(得分:0)

以下是我如何使用sample_n。这个对我有用。 db&#34; MySQL&#34;是一个20密耳的障碍物。数据库,并想要采样1 mil数据。 花了我一段时间让它发挥作用。

con <- src_mysql(dbname="MySQL")

db.smpl <- con %>% tbl("MySQL") %>%   
        tbl_df() %>% 
        sample_n(1e6, replace = F) %>% data.table()
顺便说一句,我现在找不到tbl_dt。