文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

R语言 实现将1对多数据与1对1数据互换

2024-04-02 19:55

关注

想了好长时间名字,不知道要解决的问题的名字叫什么,直接上问题demo

问题demo

现在有用户消费金额的数据:

用户 日期 金额
小明 2016-01 300
小明 2016-02 500
小明 2016-03 400
小刘 2016-01 700
小刘 2016-02 800
小刘 2016-03 600

我将以上数据格式为一对多数据(想不出好名字,敬请大家拍砖)

还有一种数据形式如下,我将如下格式数据称为1对1数据

用户 2016-01 2016-02 2016-03
小明 300 500 400
小刘 700 800 600

如何用R语言实现1对多数据与1对1数据之间的互换,在这里写了一个简单的小函数,大家有好的想法敬请提出。

生成1对1数据集的代码如下:


#创建数据集
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数据转成1对多数据

构建1对多数据的转换函数:


##data原始数据集
##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))
  #编行号结束
  result<-rbind(result,temp)
 }
 result;
}

执行代码如下:


One2MoreResult<-One2More(dt,c("2016-01","2016-02","2016-03"),"用户")

结果如下图所示:

1对多数据转成1对1数据

针对多转一我们需要安装plyr包,函数如下:


#如果有plyr,请跳过此步安装
install.packages("plyr")
library(plyr)
##data:数据集
##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数据,请注意数据类型,得出的数值结果为因子类型,请先进行转换,转换代码如下:


One2MoreResult$c1<-as.numeric(as.character(One2MoreResult$c1))

此时One2MoreResult的数据如下:

此时要按照c3进行分组,将c2列放在表头去

执行代码如下:


More2OneResult<-More2One(One2MoreResult,"c3","c2")

结果如下图所示:

完整代码


#创建数据集
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原始数据集
##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))
  #编行号结束
  result<-rbind(result,temp)
 }
 result;
}
#如果有plyr,请跳过此步安装
install.packages("plyr")
library(plyr)
##data:数据集
##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)

期望

如果有时间会解决如下问题:

1. 提高代码的通用性

2. 列名或表头名可以通过指定来解决

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。如有错误或未考虑完全的地方,望不吝赐教。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯