在使用R语言数据分析时,可以融合SQL语言使数据聚集操作更加便利,同时也可以增加对SQL语句的熟悉。借助sqldf
、DBI
、RSDLite
等包,可以在R环境中直接运用SQL语句,轻松实现数据的分组统计、汇总分析,SQL的强大查询能力简化了数据处理步骤,让复杂分析变得简单。
举个例子,使用DBI
包操作R语言自带数据集USArrests
:
library(DBI)
# 初始化一个临时的内存数据库并将一个data.frame复制到其中
con <- dbConnect(RSQLite::SQLite(), ":memory:")
data(USArrests)
dbWriteTable(con, "USArrests", USArrests)
dbListTables(con) # 将所有查询结果提取到一个data frame中
dbGetQuery(con, "SELECT * FROM USArrests") # 或者分批进行
rs <- dbSendQuery(con, "SELECT * FROM USArrests")
d1 <- dbFetch(rs, n = 10) # 以10行为单位提取数据
dbHasCompleted(rs)
d2 <- dbFetch(rs, n = -1) # 提取所有剩余数据
dbHasCompleted(rs)
dbClearResult(rs) # 清理
dbDisconnect(con)
安装sqldf
包和RSQLite
包
在进行操作前需要先安装sqldf
包和RSQLite
包
install.packages("sqldf")
install.packages("RSQLite")
随后在脚本或命令行中导入这两个包:
library(sqldf)
library(RSQLite)
sqldf
包函数参数说明
参数名称 | 描述 |
---|---|
x | SQL 查询语句,可以是单个字符串或字符串向量。如果 x 缺失,则建立一个数据库连接,后续 sqldf 语句将使用这个连接。 |
stringsAsFactors | 是否将字符型列转换为因子类型。 |
row.names | 是否为数据框添加行名列。 |
envir | 指定查找数据框的环境。 |
method | 指定输出数据框的列类型转换方式。 |
file.format | 用于读取文件到数据库的参数设置。 |
dbname | 数据库名称,对于 SQLite 和 h2 默认是 :memory: ,表示嵌入式数据库。 |
drv | 指定数据库驱动,如 "SQLite", "MySQL", "h2", "PostgreSQL" 。 |
user, password, host, port | 数据库连接的用户名、密码、主机和端口。 |
dll | SQLite 可加载扩展的名称。 |
connection | 指定已存在的数据库连接。 |
verbose | 是否显示详细输出。 |
使用案例
1.创建数据库文件
这里我将R语言自带的iris数据集制作成.sqlite
文件,在制作.sqlite文件时需要注意下,要将列命"Sepal.Length"更改为"Sepal_Length"格式,方便数据库操作。
library(RSQLite)
# 创建SQLite数据库连接
data("iris")
names(iris) <- c("Sepal_Length", "Sepal_Width", "Petal_Length", "Petal_Width", "Species")
con <- dbConnect(RSQLite::SQLite(), dbname = "iris.sqlite")
# 将iris数据集复制到数据库中的新表
dbWriteTable(con, "iris_table", iris)
# 关闭数据库连接(个人推荐每次在脚本结束时关闭连接)
dbDisconnect(con)
代码运行成功后会在工作目录中生成.sqlite文件和.sqlite-journal文件
2.查询表中数据
这里,使用刚才建立的iris.sqlite
,数据库驱动为 SQLite
,并使用 sqldf
函数执行了一个简单的 SQL 查询,即选择 iris
表中的所有列和行。查询结果存储在 iris_query_from_db
数据框中,随后被打印出来。
library(RSQLite)
library(sqldf)
# 创建SQLite数据库连接
con <- dbConnect(RSQLite::SQLite(), dbname = "iris.sqlite")
# 将iris数据集复制到数据库中的新表
dbWriteTable(con, "iris_table", iris)
# 关闭数据库连接(个人推荐每次在脚本结束时关闭连接)
dbDisconnect(con)
iris_query_from_db <- sqldf("SELECT * FROM main.iris_table WHERE Species = 'setosa'", dbname = "iris.sqlite")
# 打印结果
print(iris_query_from_db)
3.查询列名
先通过PRAGMA table_info
命令从数据库中检索iris_table
表的列信息。检索到的信息存储在一个数据框column_names
中,随后提取column_names
数据框中的name
列,并将其转换为字符向量column_names_list
,最后打印出这个列名列表。
column_names <- sqldf("PRAGMA table_info(iris_table);", dbname = "iris.sqlite")
column_names_list <- as.character(column_names$name)
print(column_names_list)
4.查询前几条记录
这里仍使用刚才创建的数据库文件,只查询前6行
iris_first_few <- sqldf("SELECT * FROM main.iris_table LIMIT 5", dbname = "iris.sqlite")
iris_first_few
5.插入数据
先创建了一个包含新数据的数据框new_row
,然后,使用dbExecute
函数和参数化查询将新数据插入到iris_table
表中,参数化查询可以帮助防止SQL注入攻击,并提高查询的安全性。
new_row <- data.frame( Sepal.Length = 5.9, Sepal.Width = 3.0, Petal.Length = 5.1, Petal.Width = 1.8, Species = "virginica"
)
dbExecute(con, "INSERT INTO iris_table (Sepal_Length, Sepal_Width,Petal_Length, Petal_Width, Species) VALUES (?, ?, ?, ?, ?)", params = list(5.9, 3.0, 5.1, 1.8, "virginica"))
6.数据筛选
这里筛选出Petal_Width
为0.2的所有数据
iris_petal_width_0_2 <- sqldf("SELECT * FROM main.iris_table WHERE Petal_Width = 0.2", dbname = "iris.sqlite")
iris_petal_width_0_2
7.数据聚合
通过sqldf()
函数执行一个SQL查询,该查询从iris表中选取每个物种(Species),并计算其平均花萼长度(Sepal_Length)和花萼宽度(Sepal_Width)。查询结果存储在一个数据框ass中,
ass <- sqldf('SELECT Species, AVG("Sepal_Length") AS Sepal_Length, AVG("Sepal_Width") AS Sepal_Width FROM iris GROUP BY Species')
ass
8. 多表连接
先创建两个数据框DF1
和DF2
,它们分别包含ID
和Value
列以及ID
和Detail
列。然后通过sqldf
函数执行一个SQL左连接查询,将DF1
和DF2
按ID
列进行连接。查询结果包含DF1
的所有列以及DF2
中的Detail
列,当ID
匹配时,Detail
列显示相应值,否则显示NA
。查询结果存储在一个数据框result
中,并打印出来以供查看。
# 建立两个数据框 DF1 和 DF2
DF1 <- data.frame(ID = 1:5, Value = 10:14)
DF2 <- data.frame(ID = 3:7, Detail = letters[1:5])
# 使用 SQL 进行连接查询
result <- sqldf("SELECT DF1.*, DF2.Detail FROM DF1 LEFT JOIN DF2 ON DF1.ID = DF2.ID")
result
最后切记有个好习惯,关闭数据库连接
dbDisconnect(con)