当大家手握数据准备大展拳脚时,会发现自己70-80%的工作其实是在清理数据!
数据不整洁,什么统计模型、高分美图暂时都不要想了。
所以今天介绍多种实用函数,让长、宽数据间的转换变得更方便。
# 安装与载入R包
install.packages("tidyr")
library(tidyr)
第一种方法,用到了一组函数 gather()和 spread()。
首先创建数据tidydata1:
# 创建数据
tidydata1 <- tibble(hospital = c("A", "B", "C"),
`2019` = c(50, 30,51), # 数字作为变量名要使用反单引号 ``
`2020` = c(55, 33,60))
tidydata1
上述数据只作为示范,为宽数据。实际中把时间直接作为变量名不太规范,不推荐这么做。
假设需要把它变成长数据,即把2019和2020合并成新变量years,以及创建第二个新变量values。
tidydata2 <- tidydata1 %>%
gather(`2019`, `2020`, key = "years", value = "values")
tidydata2
上述代码中:
%>% 符号叫做pipe,它将前面的结果传递给后面的函数作为输入。
`2019`和`2020`指定要合并的列,将其存入新变量years中。
key = "years"和value = "values"为新创建列的名称。
接下来,介绍函数spread(),它可以说是gather()的“反义词”。
数据为上面得到的tidydata2,将它变回宽数据:
tidydata3 <- spread(tidydata2, key = "years", value = "values")
tidydata3
第二组函数也是{tidyr}中的pivot_longer()和pivot_wider()函数,顾名思义,它们两个的作用分别是将数据转换成长数据以及将数据转换成宽数据。
这里用到长数据tidydata2,使用pivot_wider()将其变成宽数据:
mydata_wide <- tidydata2 %>%
pivot_wider(names_from = "years",
names_glue = "time_{years}", # 变量名添加time_,不建议用年份为变量名
values_from = "values")
mydata_wide
使用pivot_longer(),将宽数据变成长数据:
mydata_long <- mydata_wide %>%
pivot_longer(cols = -hospital,
names_to = "time",
names_prefix = "time_", # 去除变量名中的time_部分
values_to = "values")
mydata_long
第三种方法,使用R自带的函数reshape()实现长、宽数据的转换。
使用R自带的数据集Indometh,它是长数据:
summary(Indometh)
如果想将Indometh转换为宽数据,可以这么做:
wide_data <- reshape(Indometh,
direction = "wide",
idvar = "Subject",
timevar = "time",
v.names = "conc",
sep= "_")
wide_data
假如想从宽数据变回长数据也很容易:
long_data <- reshape(wide_data,
direction = "long",
idvar = "Subject",
timevar = "time",
v.names = "conc")
# 查看数据概况和前12行
summary(long_data); head(long_data, 12)
从上述两部分代码可以知道,direction = "wide"和direction = "long"决定了是长、宽数据转换的方向。
好啦,今天的内容就到这里。如果有帮助,记得分享给需要的人!