Mal*_*udo 6 postgresql r dplyr
假设我正在使用starwarsdplyr 包中的数据集,其中包含列表列(用于电影、车辆...)。为了简单起见,我们只使用名称和电影数据:
library(dplyr)
ex_data <- starwars %>%
select(name, films)
ex_data
# A tibble: 87 x 2
name films
<chr> <list>
1 Luke Skywalker <chr [5]>
2 C-3PO <chr [6]>
3 R2-D2 <chr [7]>
4 Darth Vader <chr [4]>
5 Leia Organa <chr [5]>
6 Owen Lars <chr [3]>
7 Beru Whitesun lars <chr [3]>
8 R5-D4 <chr [1]>
9 Biggs Darklighter <chr [1]>
10 Obi-Wan Kenobi <chr [6]>
# ... with 77 more rows
Run Code Online (Sandbox Code Playgroud)
我想将此数据复制到 PostgreSQL 数据库,但我希望在 SQL 中将电影列转换为文本数组类型,如下所示:
starwars=# \d test
Table "public.test"
Column | Type | Modifiers
------------+--------+-----------
name | text | not null
films | text[] |
Run Code Online (Sandbox Code Playgroud)
有没有简单的方法可以用dplyrand/or来做到这一点dbplyr?
另外,我对相反的操作感兴趣,将带有数组类型列的表从 postgreSQL db 导入到 R 中,并为数组获取一个列表类型列。
先感谢您!
下面是使用现有 R 数据库包和一些 SQL 代码的穷人的解决方法。我使用data.table包来处理数据(可以轻松适应dplyr)。
# packages
require(data.table)
require(RPostgreSQL)
# data preparation
dt = dplyr::starwars
setDT(dt)
dt = dt[ , .SD, .SDcols = c('name', 'films') ]
# list conversion
dt2 = dt[ , .(films = unlist(films)), name ]
# database I/O
drv = dbDriver('PostgreSQL')
con = dbConnect(drv,
dbname = dbname,
user = user, password = password,
host = host, port = port)
# write
dbWriteTable(con, name = 'test', value = dt2,
overwrite = TRUE, row.names = FALSE)
# convert to array in database
q = "DROP TABLE IF EXISTS test2;
CREATE TABLE test2 AS (
SELECT name, array_agg(films) AS films
FROM test
GROUP BY name
);"
dbSendQuery(con, q)
# read arrays
dt3 = dbReadTable(con, 'test')
# convert back to list columns
setDT(dt3)
dt4 = dt3[ , .(films = list(films)), name ]
dbDisconnect(con)
dbUnloadDriver(drv)
Run Code Online (Sandbox Code Playgroud)
一些想法:如果RPostgreSQL或其他数据库包之一中存在这样的功能,那就太好了。它肯定不能很好地扩展。不幸的是,我缺乏 C 语言技能来帮助实现这一点。