R語言 實(shí)現(xiàn)將1對多數(shù)據(jù)與1對1數(shù)據(jù)互換
想了好長時(shí)間名字,不知道要解決的問題的名字叫什么,直接上問題demo
問題demo
現(xiàn)在有用戶消費(fèi)金額的數(shù)據(jù):
| 用戶 | 日期 | 金額 |
|---|---|---|
| 小明 | 2016-01 | 300 |
| 小明 | 2016-02 | 500 |
| 小明 | 2016-03 | 400 |
| 小劉 | 2016-01 | 700 |
| 小劉 | 2016-02 | 800 |
| 小劉 | 2016-03 | 600 |
我將以上數(shù)據(jù)格式為一對多數(shù)據(jù)(想不出好名字,敬請大家拍磚)
還有一種數(shù)據(jù)形式如下,我將如下格式數(shù)據(jù)稱為1對1數(shù)據(jù)
| 用戶 | 2016-01 | 2016-02 | 2016-03 |
|---|---|---|---|
| 小明 | 300 | 500 | 400 |
| 小劉 | 700 | 800 | 600 |
如何用R語言實(shí)現(xiàn)1對多數(shù)據(jù)與1對1數(shù)據(jù)之間的互換,在這里寫了一個(gè)簡單的小函數(shù),大家有好的想法敬請?zhí)岢觥?/p>
生成1對1數(shù)據(jù)集的代碼如下:
#創(chuàng)建數(shù)據(jù)集
c1<-c("小明",300,500,400)
c2<-c("小劉",700,800,600)
dt<-as.data.frame(rbind(c1,c2))
names(dt)<-c("用戶","2016-01","2016-02","2016-03")
1對1數(shù)據(jù)轉(zhuǎn)成1對多數(shù)據(jù)
構(gòu)建1對多數(shù)據(jù)的轉(zhuǎn)換函數(shù):
##data原始數(shù)據(jù)集
##colList要變換的列
##要保留的主鍵列
One2More<-function(data,colList,primaryCol){
result=data.frame(NULL)
for(r in c(1:nrow(data))){
temp<-as.data.frame(t(data[r,colList]))
temp$日期<-row.names(temp)
temp<-cbind(temp,data[r,primaryCol])
names(temp)<-c("c1","c2","c3")#臨時(shí)起的名字,可按自己需求進(jìn)行修改
#編行號開始,如果沒有要求,此步可省略
resultRows<-nrow(result)
tempRows<-nrow(temp)
row.names(temp)<-c((resultRows+1):(resultRows+tempRows))
#編行號結(jié)束
result<-rbind(result,temp)
}
result;
}
執(zhí)行代碼如下:
One2MoreResult<-One2More(dt,c("2016-01","2016-02","2016-03"),"用戶")
結(jié)果如下圖所示:

1對多數(shù)據(jù)轉(zhuǎn)成1對1數(shù)據(jù)
針對多轉(zhuǎn)一我們需要安裝plyr包,函數(shù)如下:
#如果有plyr,請?zhí)^此步安裝
install.packages("plyr")
library(plyr)
##data:數(shù)據(jù)集
##primaryCol:要分組的那一列
##rowNameCols:想要變成表頭的列
More2One<-function(data,primaryCol,rowNameCols){
ddply(data,primaryCol,function(k){colNames<-k[,rowNameCols];row.names(k)<-k[,rowNameCols];k<-k[,-c(which(colnames(k)==rowNameCols | colnames(k)==primaryCol ))];t(k)})
}
注意:如果使用上文中One2MoreResult數(shù)據(jù),請注意數(shù)據(jù)類型,得出的數(shù)值結(jié)果為因子類型,請先進(jìn)行轉(zhuǎn)換,轉(zhuǎn)換代碼如下:
One2MoreResult$c1<-as.numeric(as.character(One2MoreResult$c1))
此時(shí)One2MoreResult的數(shù)據(jù)如下:

此時(shí)要按照c3進(jìn)行分組,將c2列放在表頭去
執(zhí)行代碼如下:
More2OneResult<-More2One(One2MoreResult,"c3","c2")
結(jié)果如下圖所示:

完整代碼
#創(chuàng)建數(shù)據(jù)集
c1<-c("小明",300,500,400)
c2<-c("小劉",700,800,600)
dt<-as.data.frame(rbind(c1,c2))
View(dt)
names(dt)<-c("用戶","2016-01","2016-02","2016-03")
##data原始數(shù)據(jù)集
##colList要變換的列
##要保留的主鍵列
One2More<-function(data,colList,primaryCol){
result=data.frame(NULL)
for(r in c(1:nrow(data))){
temp<-as.data.frame(t(data[r,colList]))
temp$日期<-row.names(temp)
temp<-cbind(temp,data[r,primaryCol])
names(temp)<-c("c1","c2","c3")
#編行號開始,如果沒有要求,此步可省略
resultRows<-nrow(result)
tempRows<-nrow(temp)
row.names(temp)<-c((resultRows+1):(resultRows+tempRows))
#編行號結(jié)束
result<-rbind(result,temp)
}
result;
}
#如果有plyr,請?zhí)^此步安裝
install.packages("plyr")
library(plyr)
##data:數(shù)據(jù)集
##primaryCol:要分組的那一列
##rowNameCols:想要變成表頭的列
More2One<-function(data,primaryCol,rowNameCols){
ddply(data,primaryCol,function(k){colNames<-k[,rowNameCols];row.names(k)<-k[,rowNameCols];k<-k[,-c(which(colnames(k)==rowNameCols | colnames(k)==primaryCol ))];t(k)})
}
One2MoreResult<-One2More(dt,c("2016-01","2016-02","2016-03"),"用戶")
View(One2MoreResult)
One2MoreResult$c1<-as.numeric(as.character(One2MoreResult$c1))
More2OneResult<-More2One(One2MoreResult,"c3","c2")
View(More2OneResult)
期望
如果有時(shí)間會解決如下問題:
1. 提高代碼的通用性
2. 列名或表頭名可以通過指定來解決
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
R語言ggplot2設(shè)置圖例(legend)的操作大全
ggplot2是一個(gè)繪制可視化圖形的R包,汲取了R語言基礎(chǔ)繪圖系統(tǒng)(graphics)和l?attice包的優(yōu)點(diǎn),下面這篇文章主要給大家介紹了關(guān)于R語言ggplot2設(shè)置圖例(legend)的操作大全,需要的朋友可以參考下2022-07-07
R語言繪圖學(xué)習(xí)教程VennDiagram繪制venn
這篇文章主要為大家介紹了R語言繪圖學(xué)習(xí)教程VennDiagram繪制venn的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
R語言中assign函數(shù)和get函數(shù)的用法
這篇文章主要介紹了R語言中assign函數(shù)和get函數(shù)的用法說明,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04
R語言導(dǎo)入導(dǎo)出數(shù)據(jù)的幾種方法匯總
這篇文章主要給大家總結(jié)介紹了R語言導(dǎo)入導(dǎo)出數(shù)據(jù)的幾種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03

