【r<-高级】R-操作数据库

作者: 王诗翔 | 来源:发表于2018-08-25 15:52 被阅读10次

在阅读之前我有必要进行申明,因为使用的是RMD文档,所以每次RENDER的时候都会读取数据库,所以结果显示不一样正常,有的也加了overwriteappend选项。显示的结果不一定与实际读者操作的结果一致。

内容:

  • 了解关系型数据库
  • 使用SQL工具

使用数据库能够有效地应对超出计算机内存容量的数据存储问题,还可以根据用户提供的条件,对数据库中的数据进行查询,这也使在数据库中更新现有记录和插入新数据的操作变得简单。

操作关系型数据库

关系型数据库就是一个由表和表之间的关系组成的集合。数据库中的表和R中的数据框有相同地形式。表之间可以互相关联,让我们能够轻松合并多张表信息。

下面从最简单数据库开始,SQLite(http://sqlite.org/是一个轻量级的数据库引擎。

在R中操作SQLite数据库需要用RSQLite扩展包。运行下面代码:

if(!require("RSQLite")) install.packages("RSQLite")
#> 载入需要的程辑包:RSQLite

创建SQLite数据库

现在在博客R目录下创建一个data目录,用来存储数据库:

if (!dir.exists("../../R/data")) dir.create("../../R/data")

接下来载入RSQLite包,提供数据库驱动SQLite()和数据库文件example.sqlite建立连接。如果目标文件不存在,数据库驱动会创建一个新的空文件,即空SQLite数据库:

library(RSQLite)

con = dbConnect(SQLite(), "../../R/data/example.sqlite")

数据库连接con是介于用户和系统中间的一层。我们可以创建一个连接,并且连接到关系型数据库,并通过这个连接实现查询、抽取以及更新数据。后续将一直使用这个连接,直到这个连接被关闭。

我们可以在关系数据库中创建新表,表看起来和R里的数据框是一样的。

下面创建一个数据框,并将它作为表插入数据库中。

example1 = data.frame(
    id = 1:5,
    type = c("A", "A", "B", "B", "C"),
    score = c(8, 9, 8, 10, 9),
    stringsAsFactors = FALSE
)

example1
#>   id type score
#> 1  1    A     8
#> 2  2    A     9
#> 3  3    B     8
#> 4  4    B    10
#> 5  5    C     9

现在进行写入:

dbWriteTable(con, "example1", example1, overwrite = TRUE)

接下来使用dbDisconnect()断开数据库连接,这样con便不可用了。

dbDisconnect(con)

向一个数据库写入多张表格

现在我们将ggplot2diamonds数据集和nycflights13中的flights数据集作为两张表格写入数据库中。

if(!require("ggplot2")) install.packages("ggplot2")
#> 载入需要的程辑包:ggplot2

if(!require("nycflights13")) install.packages("nycflights13")
#> 载入需要的程辑包:nycflights13

data("diamonds", package = "ggplot2")
data("flights", package = "nycflights13")

我们重复之前的操作流程:

con = dbConnect(SQLite(), "../../R/data/datasets.sqlite")
dbWriteTable(con, "diamonds", diamonds, row.names = FALSE, overwrite = TRUE)
dbWriteTable(con, "flights", flights, row.names = FALSE, overwrite = TRUE)
dbDisconnect(con)

这里使用overwrite=TRUE的目的是防止多次添加同一张表报错。

现在数据库中有两张表了。

向表中追加数据

下面先生成几个数据块,然后增加到数据库的表中:

con = dbConnect(SQLite(), "../../R/data/example2.sqlite")

# 先移除之前的表
dbRemoveTable(con, "products")
chunk_size = 10
id = 0
for (i in 1:6){
    chunk = data.frame(id = ((i - 1L) * chunk_size):(i * chunk_size -1L),
                       type = LETTERS[[i]],
                       score = rbinom(chunk_size, 10, (10-i)/10),
                       stringsAsFactors = FALSE)
    dbWriteTable(con, "products", chunk,
                 append = i > 1, row.names = FALSE)
}

dbDisconnect(con)

每次代码块都生成一个数据框,包含一些确定数据和随机数,我们将这些数据记录追加到一个名为products的表中。

访问表和表中字段

当有了数据库和数据,我们可以进行数据访问。比如所有表的名字或某个表的列。

con = dbConnect(SQLite(), "../../R/data/datasets.sqlite")

使用dbExistsTable()可以检查数据库是否存在某张表:

dbExistsTable(con, "diamonds")
#> [1] TRUE

dbExistsTable(con, "mtcars")
#> [1] FALSE

下面列出该数据库的所有表:

dbListTables(con)
#> [1] "diamond_selector" "diamonds"         "flights"

对于某一张表,我们可以使用dbListFields()列出表的列名(或字段):

dbListFields(con, "diamonds")
#>  [1] "carat"   "cut"     "color"   "clarity" "depth"   "table"   "price"  
#>  [8] "x"       "y"       "z"

dbWriteTable()相反,adReadTable()将表格读入为数据框:

db.diamonds = dbReadTable(con, "diamonds")
dbDisconnect(con)

head(db.diamonds)
#>   carat       cut color clarity depth table price    x    y    z
#> 1  0.23     Ideal     E     SI2  61.5    55   326 3.95 3.98 2.43
#> 2  0.21   Premium     E     SI1  59.8    61   326 3.89 3.84 2.31
#> 3  0.23      Good     E     VS1  56.9    65   327 4.05 4.07 2.31
#> 4  0.29   Premium     I     VS2  62.4    58   334 4.20 4.23 2.63
#> 5  0.31      Good     J     SI2  63.3    58   335 4.34 4.35 2.75
#> 6  0.24 Very Good     J    VVS2  62.8    57   336 3.94 3.96 2.48
str(db.diamonds)
#> 'data.frame':    53940 obs. of  10 variables:
#>  $ carat  : num  0.23 0.21 0.23 0.29 0.31 0.24 0.24 0.26 0.22 0.23 ...
#>  $ cut    : chr  "Ideal" "Premium" "Good" "Premium" ...
#>  $ color  : chr  "E" "E" "E" "I" ...
#>  $ clarity: chr  "SI2" "SI1" "VS1" "VS2" ...
#>  $ depth  : num  61.5 59.8 56.9 62.4 63.3 62.8 62.3 61.9 65.1 59.4 ...
#>  $ table  : num  55 61 65 58 58 57 57 55 61 61 ...
#>  $ price  : int  326 326 327 334 335 336 336 337 337 338 ...
#>  $ x      : num  3.95 3.89 4.05 4.2 4.34 3.94 3.95 4.07 3.87 4 ...
#>  $ y      : num  3.98 3.84 4.07 4.23 4.35 3.96 3.98 4.11 3.78 4.05 ...
#>  $ z      : num  2.43 2.31 2.31 2.63 2.75 2.48 2.47 2.53 2.49 2.39 ...

相关文章

网友评论

    本文标题:【r<-高级】R-操作数据库

    本文链接:https://www.haomeiwen.com/subject/efjgiftx.html