不想排版,心情也不好,但是這個知識點很重要,尤其是學習R語言的朋友,請仔細看~
一直以來我都是隨便看了點R的編程教程,因為我學了一點點C,所以還算有基礎,現在基本上簡單看看教程就能懂一門語言了,區別只是熟練度而已。R用得比較多,所以還算擅長,但是很多快捷應用的地方,我總是寄希望於到時候再查資料,所以沒能用心的記住,這次花了點時間好好整理了一下R裡面關於數據操作的重點,我想,以後再碰到類似的數據處理要求,應該很快能解決了把。
首先看看排序:在R中,和排序相關的函數主要有三個:sort(),rank(),order()。
sort(x)是對向量x進行排序,返回值排序後的數值向量。
rank()是求秩的函數,它的返回值是這個向量中對應元素的「排名」。
order()的返回值是對應「排名」的元素所在向量中的位置。
其中sort(x)等同於x[order(x)]
下面以一小段R代碼來舉例說明:
> x<-c(97,93,85,74,32,100,99,67)
> sort(x)
[1] 32 67 74 85 93 97 99 100
> order(x)
[1] 5 8 4 3 2 1 7 6
> rank(x)
[1] 6 5 4 3 1 8 7 2
> x[order(x)]
[1] 32 67 74 85 93 97 99 100
其中比較有用的order,它可以用來給數據框進行排序
dat[order(dat[,1]),] 以該數據框的第一列進行排序
dat[order(dat[,1],dat[,2]),] 以該數據框的第一列為主要次序,第二列為次要序列進行排序
然後我們看看集合運算:
在R裡面除了簡單的對兩個向量求交集併集補集之外,比較重要的就是match和 %in% 了,需要重點講講。
#首先對集合A,B,C賦值
> A<-1:10
> B<-seq(5,15,2)
> C<-1:5
> #求A和B的併集
> union(A,B)
[1] 1 2 3 4 5 6 7 8 9 10 11 13 15
> #求A和B的交集
> intersect(A,B)
[1] 5 7 9
> #求A-B
> setdiff(A,B)
[1] 1 2 3 4 6 8 10
> #求B-A
> setdiff(B,A)
[1] 11 13 15
> #檢驗集合A,B是否相同
> setequal(A,B)
[1] FALSE
> #檢驗元素12是否屬於集合C
> is.element(12,C)
[1] FALSE
> #檢驗集合A是否包含C
> all(C%in%A)
[1] TRUE
> all(C%in%B)
從上面可以看到%in%這個操作符只返回邏輯向量TRUE 或者FALSE,而且返回值應該與%in%這個操作符前面的向量程度相等。也就是說它相當於遍歷了C裡面的一個個元素,判斷它們是否在B中出現過,然後返回是或者否即可。
而match(C,B)的結果就很不一樣了,它的返回結果同樣與前面的向量等長,但是它並非返回邏輯向量,而是遍歷了C裡面的一個個元素,判斷它們是否在B中出現過,如果出現就返回在B中的索引號,如果沒有出現,就返回NA。
>B
[1] 5 7 9 11 13 15
>C
[1] 1 2 3 4 5
>match(C,B)
[1] NA NA NA NA 1
>C%in%B
[1] FALSE FALSE FALSE FALSE TRUE
接下來我們看看reshape:這是一個需要安裝的包,起得就是R裡面最經典的把長型數據變寬,和把寬數據拉長的作用。
其中melt函數是把很寬的數據拉長,它就是需要指定幾列數據是保證不被融合的, 其餘每一列數據都必須被融合到一列了,融合後的這一列數據每個元素旁邊就用列名來標記該數據來自於哪一列。
# example of melt function
library(reshape)
mdata <- melt(mydata, id=c("id","time"))
融合後的數據如下:
idtimevariablevalue11x1512x1321x1622x1211x2612x2521x2122x24可以看到variable列裡面有兩個不同的元素,說明是把舊數據中的兩列給融合了,融合後的一個很長的列就是value
而cast函數的功能就是把剛才融合好的數據給還原。
# cast the melted data
# cast(data, formula, function)
subjmeans <- cast(mdata, id~variable, mean)
timemeans <- cast(mdata, time~variable, mean)
可以看到它們返回的結果是:
subjmeans
timemeans
可以看到cast函數比較複雜一點,formula公式右邊的變量是需要拆開的variable,這一列變量有多少不重複元素,就新增多少列,左邊的變量是行標記了,其餘所有數據都會被計算一下再放在合適的位置。
在reshape2這個包裡面還進化出來dcast和acast函數,功能大同小異。
最後我們來看看merge函數:
這個函數的功能非常強大,類似於SQL語句裡面的join系列函數
測試數據如下,它們這兩個表的連接是作者名
如果要實現類似sql裡面的inner join 功能,則用代碼
m1 <- merge(authors, books, by.x = "surname", by.y = "name")
如果要實現left join功能則用代碼
m1 <- merge(authors, books, by.x = "surname", by.y = "name",all.x=TRUE)
right join功能代碼
m1 <- merge(authors, books, by.x = "surname", by.y = "name",all.y=TRUE)
all join功能代碼
m1 <- merge(authors, books, by.x = "surname", by.y = "name",all=TRUE)
關於單變量匹配的總結就是這些,但對於多變量匹配呢,例如下面兩個表,需要對k1,k2兩個變量都相等的情況下匹配
x <- data.frame(k1 = c(NA,NA,3,4,5), k2 = c(1,NA,NA,4,5), data = 1:5)
y <- data.frame(k1 = c(NA,2,NA,4,5), k2 = c(NA,NA,3,4,5), data = 1:5)
匹配代碼如下merge(x, y, by = c("k1","k2")) #inner join
另外一個多行匹配的例子如下:
我們的測試數據如上,這兩個表的連接在於作者名。下面這兩個語句等價
merge(authors, books, by=1:2)
merge(authors, books, by.x=c("FirstName", "LastName"),
by.y=c("AuthorFirstName", "AuthorLastName"),
all.x=TRUE)
都可以把兩張表關聯起來。
當然,在我搜索資料的時候,發現了另外一個解決問題的方法:
A[with(A, paste(C1, C2, sep = "\r")) %in% with(B, paste(C1, C2, sep="\r")), ]
參考:http://blog.sina.com.cn/s/blog_6caea8bf0100spe9.html
http://blog.sina.com.cn/s/blog_6caea8bf010159dt.html
http://blog.csdn.net/u014801157/article/details/24372441
http://www.statmethods.net/management/reshape.html
https://docs.tibco.com/pub/enterprise-runtime-for-R/1.5.0_may_2013/TERR_1.5.0_LanguageRef/base/merge.html
http://r.789695.n4.nabble.com/Matching-multiple-columns-in-a-data-frame-td890832.html
http://bbs.pinggu.org/thread-3234639-1-1.html
http://www.360doc.com/content/14/0821/13/18951041_403561544.shtml
http://developer.51cto.com/art/201312/423612.htm