dplyr::tbl 返回列表而不是 table

dplyr::tbl returning list instead of table

我正在尝试使用 RStudio 中的 dplyr 来操作 MS SQL 服务器数据库中的 tables。我使用 DBI、ODBC 成功连接到数据库。

代码:

library(DBI)
library(odbc)
library(dplyr)
library(dbplyr)
con <- dbConnect(odbc(), 
                 Driver = "SQL Server",
                 Server = "myserver",
                 database = "ABC",
                 UID = "sqladmin",
                 PWD = "pwd",
                 port = '14333')

data <- tbl(con, "abc")

abc 是数据库 ABC 中的 table。连接成功(我可以查看 tables 和字段)但是 dplyr::tbl 返回一个列表 2 而不是返回 table abc.所以 data 是一个列表而不是 table。这段代码哪里出错了?

模式是ABC --> dbo --> abc

代码按预期运行。您所看到的只是 RStudio 数据检查器中类型显示的限​​制:tbl 返回的实际类型是 S3 class tbl_SQLiteConnection 的 object 但它被实现为嵌套 list(类似于 data.frame 被实现为列列表)。

您将能够按预期使用 data。您还可以调用 as_tibble(data) 来获得正确的小标题……但您不需要这样做 来使用它!

基于@Konrad 的回答,一些额外的注意事项:

  • 本地数据帧和远程数据帧之间存在区别。 remote_data <- tbl(connection, "database_table_name") 创建一个远程数据框。数据存储在源数据库中,但 R 有一个指向数据库的指针,可用于查询它。

  • 您可以使用 local_data <- collect(remote_data)local_data <- as.dataframe(remote_data) 将远程数据帧中的数据加载到 R 内存中。根据远程数据的大小,这可能会非常慢,或者由于内存不足而导致 R 崩溃。

  • 本地和远程数据帧都是数据帧。 class(remote_data)class(local_data) 将 return 预期的类型:tbl(小标题)。远程数据帧被实现为一个列表,因为它需要存储与本地数据帧不同的信息。尝试 head(remote_data, 100) 查看远程 table.

    的前 100 行
  • 远程数据帧可以使用(大多数)标准 dplyr 命令进行操作。这些由 dbplyr 翻译成相应的数据库语法并在数据库上执行。

远程 tables 的一个很好的用途是在将汇总数据拉入本地 R 内存以进行进一步处理之前对大型 table 执行初始过滤和汇总。例如:

library(DBI)
library(odbc)
library(dplyr)
library(dbplyr)
con <- dbConnect(odbc(), 
                 Driver = "SQL Server",
                 Server = "server_name",
                 database = "database_name",
                 UID = "sqladmin",
                 PWD = "pwd",
                 port = '14333')

remote_data <- tbl(con, "database_table_name")

# preview remote table
head(remote_data)

# summarize
prepared_data <- remote_data %>%
  filter(column_1 >= 10) %>%
  group_by(column_2) %>%
  summarize(total = sum(column_2), .groups = 'drop')

# check query of prepared table
show_query(prepared_data)

# draw summarised table into local memory
local_summarised_data <- collect(prepared_data)