前言
做数据分析以及制作表格的时候,会遇到长宽格式数据之间相互转换的问题,之前介绍了如果在Hive是使用sql语句实现,现介绍一下如何在R语言中实现长宽格式数据相互转换。
长宽格式数据
之前在【Hive】实现长格式数据转换成宽格式数据举了一个栗子:
宽格式数据:每个变量单独成一列为宽格式数据,变量的所有属性都在同一行。
长格式数据:长数据中变量的ID没有单独列成一列,而是整合在同一列。
需求描述
下面左右两种长宽格式数据相互转换:
需求实现
R语言中有两个包中的函数可以实现长宽格式数据的相关转换:
数据准备
##长格式数据
data <- data.frame(
user_no = rep(c("u001", "u002", "u003"), each = 6),
message = rep(c("name", "age", "sex", "education", "regtime", "first_buytime"), times = 3),
detail = c("Sulie", "25", "male", "master", "2018/1/2", "2018/1/3", "LuBan", "30", "male", "Bachelor",
"2018/3/4", "2018/5/5", "ZhenJi", "27", "female", "PhD", "2018/4/3","2018/5/4")
)
##宽格式数据
data1 <- data.frame(
user_no = c("u001", "u002", "u003"),
name = c("SuLie", "LuBan", "ZhenJi"),
sex = c("male", "male", "female"),
age = c(25, 30, 27),
education = c("master", "Bachelor", "PhD"),
regtime = c("2018/1/2", "2018/3/4", "2018/4/3"),
first_buytime = c("2018/1/3", "2018/5/5", "2018/5/4")
)
reshape2包实现长宽数据转换
##长格式数据转换成宽格式数据
library(reshape2)
library(dplyr)
dcast(
data = data,
user_no ~ message
##左侧是要保留的字段,右侧是要分割的字段,可以理解为key
##这样汇总的就是value值了
)
##宽格式数据转换成长格式数据
melt(data1,
id.vars=c("user_no"), ##要保留的字段
variable.name = "message", #理解为key
value.name = "detail" #理解为value
) %>%
arrange(user_no)
运行结果:
长格式数据转换成宽格式数据运行结果
宽格式数据转换成长格式数据运行结果
tidyr包实现长宽数据转换
##长格式数据转换成宽格式数据
library(tidyr)
library(dplyr)
spread(
data = data,
key = "message", ##key键,原来表中字段
value = "detail" ##value值,原来表中字段
)
##宽格式数据转换成长格式数据
gather(
data = data1,
key = "message", ##key键,新增字段
value = "detail", ##value值,新增字段
name:first_buytime
) %>%
arrange(user_no)
运行结果:
长格式数据转换成宽格式数据运行结果
宽格式数据转换成长格式数据运行结果
总结
R语言reshap2和tidyr包都可以实现长宽格式数据相互转换,相比较而言,更喜欢tidyr包中的实现方式,与Hive中类似,中间过渡map格式类型数据,key键和value值明确,结合sql中map格式数据更容易理解R语言tidyr包中实现方式。