數據庫是極其重要的R語言數據導入源數據之地,讀入包有sqldf、RODBC等。跟SQL server相連有RODBC,跟mySQL鏈接的有RMySQL。但是在R里面,回傳文本會出現截斷的情況,這一情況可把我弄得有點手足無措。
一、數據庫讀入——RODBC包
CRAN 里面的包 RODBC 提供了 ODBC的訪問接口:
odbcConnect 或 odbcDriverConnect (在Windows圖形化界面下,可以通過對話框選擇數據庫) 可以打開一個連接,返回一個用於隨后數據庫訪問的控制(handle)。 打印一個連接會給出ODBC連接的一些細節,而調用 odbcGetInfo 會給出客戶端和服務器的一些細節信息。
在一個連接中的表的細節信息可以通過函數 sqlTables 獲得。
函數 sqlSave 會把 R 數據框復制到一個數據庫的表中, 而函數 sqlFetch 會把一個數據庫中的表拷貝到 一個 R 的數據框中。
通過sqlQuery進行查詢,返回的結果是 R 的數據框。(sqlCopy把一個 查詢傳給數據庫,返回結果在數據庫中以表的方式保存。) 一種比較好的控制方式是首先調用 odbcQuery, 然后 用 sqlGetResults 取得結果。后者可用於一個循環中 每次獲得有限行,就如函數 sqlFetchMore 的功能。
連接可以通過調用函數 close 或 odbcClose 來關閉。 沒有 R 對象對應或不在 R 會話后面的連接也可以調用這兩個函數來關閉, 但會有警告信息。
[plain] view plain copy
在CODE上查看代碼片派生到我的代碼片
#安裝RODBC包
install.packages("RODBC")
library(RODBC)
mycon<-odbcConnect("mydsn",uid="user",pwd="rply")
#通過一個數據源名稱(mydsn)和用戶名(user)以及密碼(rply,如果沒有設置,可以直接忽略)打開了一個ODBC數據庫連接
data(USArrests)
#將R自帶的“USArrests”表寫進數據庫里
sqlSave(mycon,USArrests,rownames="state",addPK=TRUE)
#將數據流保存,這時打開SQL Server就可以看到新建的USArrests表了
rm(USArrests)
#清除USArrests變量
sqlFetch(mycon, "USArrests" ,rownames="state")
#輸出USArrests表中的內容
sqlQuery(mycon,"select * from USArrests")
#對USArrests表執行了SQL語句select,並將結果輸出
sqlDrop(channel,"USArrests")
#刪除USArrests表
close(mycon)
#關閉連接
本段來自R語言︱文件讀入、讀出一些方法羅列(批量xlsx文件、數據庫、文本txt、文件夾)
1、sqlSave函數
sqlSave(channel, dat, tablename = NULL, append = FALSE,
rownames = TRUE, colnames = FALSE, verbose = FALSE,
safer = TRUE, addPK = FALSE, typeInfo, varTypes,
fast = TRUE, test = FALSE, nastring = NULL)
其中這個函數的使用還是很講究的,參數的認識很重要。
append代表是否追加,默認不追加,如果一張已經有數據的表,就可以用append追加新的數據,需要同樣的column,一般開個這個就行。
rownames,可以是邏輯值,也可以是字符型。
colnames,列名;
verbose,默認為FALSE,是否發送語句到R界面,如果TRUE,那么每條上傳數據就會出現在命令欄目致之中。
addPK,是否將rownames指定為主鍵。
2、sqlUpdate函數
sqlUpdate(channel, dat, tablename = NULL, index = NULL,
verbose = FALSE, test = FALSE, nastring = NULL,
fast = TRUE)
更新已經存在的表格,需要包括已經存在的列。
——————————————————————————————————————————————
二、sqldf包
本包的學習來自CDA DSC課程,L2-R語言第四講內容,由常老師主講。與RODBC的區別在於,前面是直接調用數據庫SQL中的數據;而該包是在R語言環境中,執行SQL搜索語言。
組合使用:RODBC從數據庫讀入環境,sqldf進行搜索(適合SQL大神)。
其他函數的類似功能可以看:R語言數據集合並、數據增減
1、SQL基本特點
SQL語句語句特點:先全局選擇,再局部選擇
Select * from sale where year=2010 and ...
where后面可以接很多,有比較運算符,算數運算符,邏輯運算符。
比較運算符號:=(等於,不是雙引號);!=(不等於);>,<,>=,<=
算數運算符:*,/,+,-
邏輯運算符:&&(and,與), ||(or,或) ,!(,not非)
2、數據篩選與排序
數據篩選可以有subset函數,排序有order/sort函數
#選擇表中指定列*/
sqldf("select year,market,sale,profit from sale")
#選擇滿足條件的行*/
sqldf("select * from sale where year=2012 and market='東'")
#語句特點,先抽取全局數據,然后再執行局部選擇
#字符單引號,切記
#對行進行排序*/
sqldf("select year,market,sale,profit
from sale
order by year")
數據篩選:sqldf可以執行選擇表中指定指標、滿足條件的行(注意:抽取滿足條件的行的字符時,字符型需要用單引號),語法結構是:
select 指標名稱 from 數據集 where 某指標=條件
排序order:按照某變量排序,語法結構:
select 指標名稱(或全部)from 數據集 order by 指標名稱
3、數據合並——縱向連接
數據合並的方法很多,基本函數包中有merge、cbind/rbind,以及一些專業的包plyr、dplyr、data.table等
rbind/cbind對數據合並的要求比較嚴格:合並的變量名必須一致;數據等長;指標順序必須一致。
sqldf就不會這么苛刻,並參照了一些集合查詢的方法(關於基礎包的集合查詢可參考:R語言︱集合運算)。
(1)並——union
UNION3<-sqldf("select * from one union select * from two")
#合並后去重,rbind是合並后不去重
UNION_all<-sqldf("select * from one union all select * from two")
#all可以支持,合並后不去重
rbind/cbind是將數據一股腦子全部帖在一起,只合並不去重;sqldf則可以自行選擇,語法結構:
select * from 數據集1 union (all) select * from 數據集2
其中的all代表不去重,一起加進來。
(2)差(except)、交(Intersect)
#EXCEPT_差集
#不存在all
EXCEPT<-sqldf("select * from one EXCEPT select * from two")
#INTERSECT——交集
INTERSECT<-sqldf("select * from one INTERSECT select * from two")
差集就是找兩個數據集的不同的數據,而且是數據集1中,去掉重復的數值;並集則是兩個數據集的重合(去重可以用)之處。
4、數據合並——橫向連接
橫向連接有三種類型:交叉連接(笛卡爾乘積,大亂燉所有數據重新排列組合合並起來,一般在實驗設計涉及全排列的時候可以很好地使用)、內連接(篩選匹配到的數據)、外連接。
其中,sqldf 中的右連接、全連接已經失效,一般情況下會大多選擇左聯結。
(1)內連接——匹配到完全一致的
> inner1<- merge(table1, table2, by = "id", all = F);inner1 #篩選相同id,F為只連接匹配到的,T為沒有匹配到的賦值NA
id a b
1 3 c e
> inner2<-inner_join(table1, table2, by = "id");inner2 #與merge完全一致
id a b
1 3 c e
> inner3<-sqldf("select * from table1 as a inner join table2 as b on a.id=b.id");inner3 #內連接
id a id b
1 3 c 3 e
> inner4<-sqldf("select * from table1 as a,table2 as b where a.id=b.id");inner4 #笛卡爾積
id a id b
1 3 c 3 e
匹配到完全一致、相同的,基礎包merge=dplyr的inner_join=sqldf包中的inner join。當然輸出結果中,sqldf中會蹦出來兩個id,可以進行刪除。
其中sql包中的Inner join語法結構為:
select * from 數據集1 as a inner join 數據集2 as b on a.指標名稱=b.指標名稱
(2)左連接——最有效,以數據集1為准,匹配到的+為匹配到的
> left1<- merge(table1, table2, by = "id", all.x = TRUE);left1 #按照id連接所有信息包括進去
id a b
1 1 a <NA>
2 2 b <NA>
3 3 c e
> left2<-left_join(table1, table2, by = "id");left2
id a b
1 1 a <NA>
2 2 b <NA>
3 3 c e
> left3<-sqldf("select * from table1 as a left join table2 as b on a.id=b.id");left3
id a id b
1 1 a NA <NA>
2 2 b NA <NA>
3 3 c 3 e
基礎包中的merge,當all=F就是內連接,all=T就是全連接,all.x=T就是左聯結,all.y=T就是右連接(merge函數首選all=T,全連接);dplyr中的left_join也可以實現merge,all=T效果
sqldf中的語法結構:
select * from 數據集1 as a left join 數據集2as b on a.指標名稱=b.指標名稱
4、數據去重
#刪除重復的行*/
sqldf("select DISTINCT year from sale")
解讀:distinct跟unique去重功能差不多,語法特點:
select DISTINCT 指標名稱 from 數據集
——————————————————————————————————————————————————————
應用一:R語言中文本回傳SQL出現截斷(truncated )現象,怎么辦?
R語言中用sqlSave函數,把文本回傳的時候回出現這樣的問題,文本超過255個字符的會出現截斷truncated現象,因為回傳到SQL之后,規定的字符數即為varchar(255),所以會出現截斷現象。
如果出現這樣的截斷現象該如何解決呢?
解決辦法一:修改SQL Server的字符
先創建一個表,然后把那個字符型格式修改為varchar(4000),或者其他格式,不能修改成max,會報錯,造成Rstudio崩潰。當然,也可以先sqlSave一個版本過去(就幾條內容),然后修改一下格式之后,繼續append追加內容進行。
SQL Server 2008中在修改數據類型的時候,會報錯,一直保存不了,需要按照以下的內容設置一下:
選擇菜單 工具-〉選項-〉表設計器(Designers)-〉表設計器和數據庫設計器table and database designers。然后去掉“ 阻止保存要求重新創建表的更改”(prevent saving changes that require table re-creation)前面的勾。重新啟動MSSQL SERVER 2008可以解決該問題。 (來源博客:http://franciswmf.iteye.com/blog/1962550)
但是筆者在嘗試該辦法的時候,總是修改之后就卡死,所以無奈選擇第二條路。
解決辦法二:從R中導出然后導入SQL Server
筆者嘗試過,導出csv/txt但是直接用SQL Server內嵌工具,“SQL Server Import and export Wizard”對於csv/txt導入都十分麻煩,導入出現很多問題。
所以最后是用csv-轉excel-用上述工具導入。
問題一:R語言中,用write.csv時候,用office打開,多出了很多行?
如果文本字符長度很大,那么就會出現內容串到下面一行的情況,譬如10行的內容,可能變成了15行。好像office默認單個單元格的字符一般不超過2500字符,超過就會給到下一行。
所以筆者在導入5W條數據時候,多出了很多行,於是只能手動刪除。
如果用txt格式導出,用Notepad++打開是好的,但是用excel打開又多出來不少行,所以用excel打開是用代價的。
但是由於excel是最好的導入SQL的格式,於是不得不手工刪除,同時犧牲一部分的內容。
問題二:如何使用SQL Server Import and export Wizard?
1、choose a Data Source界面(注意勾選,在第一個數據行中顯示列名稱)
2、Data Source中,有Flat File Source 欄目,就是用來做csv、txt格式的;還有一個excel選項是專門針對excel
3、導入數據界面,你需要輸入服務器名稱,已經相應的數據庫名稱;
4、選擇源表和源視圖,你可以通過”目標“欄目新建,也可以導入已經有的表格,當然第一次導入,筆者推薦直接導入新表,注意看檢查一下下面的一個欄目”編輯映射“
5、運行語句。
其中,如果你是第二次導入已經有的表,那么在第四步,”編輯映射“時,就需要看清楚是否與已有的數據列表一一對應。
同時,如果第二次導入的表有表頭名稱,只要第一步勾選列名稱,也是沒有關系的,導入后不算入數據之中。
主要教程來源於:http://www.xlgps.com/article/61446.html
問題三:通過SQL代碼導入
相關內容可參考博客:
http://www.it165.net/database/html/201310/4632.html
http://www.cnblogs.com/wangshenhe/archive/2013/04/27/3047092.html
——————————————————————————————————————————————————————
貼張dplyr包的用法
---------------------
作者:悟乙己
來源:CSDN
原文:https://blog.csdn.net/sinat_26917383/article/details/51601539
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!