Converting data between wide and long format 在宽、长格式之间转换数据

R语言中的大多数函数希望数据是长格式 但是,像 SPSS 通常使用宽格式数据 当你想把将数据从宽转换为长格式

常用的有两种方法: 1、gather() 和 spread() 来自 tidyr 包。 2、melt() 以及 dcast() 来自 reshape2 包

还有许多不常用的函数也可以实现: 1、reshape() 函数,不过它不是 reshape2 包的一部分,是 R base 包 2、stack() 和 unstack()

示例数据

olddata_wide <- read.table(header=TRUE, text='

subject sex control cond1 cond2

1 M 7.9 12.3 10.7

2 F 6.3 10.6 11.1

3 F 9.5 13.1 13.8

4 M 11.5 13.4 12.9

')

# 确保 subject 这一列是因子

olddata_wide$subject <- factor(olddata_wide$subject)

olddata_long <- read.table(header=TRUE, text='

subject sex condition measurement

1 M control 7.9

1 M cond1 12.3

1 M cond2 10.7

2 F control 6.3

2 F cond1 10.6

2 F cond2 11.1

3 F control 9.5

3 F cond1 13.1

3 F cond2 13.8

4 M control 11.5

4 M cond1 13.4

4 M cond2 12.9

')

# 确保 subject 这一列是因子

olddata_long$subject <- factor(olddata_long$subject)

使用tidyr 包

1、从宽到长: 使用tidyr的函数gather()

olddata_wide

#> subject sex control cond1 cond2

#> 1 1 M 7.9 12.3 10.7

#> 2 2 F 6.3 10.6 11.1

#> 3 3 F 9.5 13.1 13.8

#> 4 4 M 11.5 13.4 12.9

library(tidyr)

# 用法

gather(

data,

key = "key",

value = "value",

...,

na.rm = FALSE,

convert = FALSE,

factor_key = FALSE

)

# 函数gather()的参数:

# - data: 目标数据集

# - key: 新的列的名称(可以有多个)

# - value: 选择用来填充key列的列

# - ...: value可以有多个

# - factor_key: 将新的列转为因子 (FALSE为向量)

# - na.rm: 删除缺失的值. 默认为FALSE

data_long <- gather(olddata_wide, condition, measurement, control:cond2, factor_key=TRUE)

## condition、measurement 是新增的列

## 这两列的数据是来自原数据框 control:cond2 这三列

data_long

#> subject sex condition measurement

#> 1 1 M control 7.9

#> 2 2 F control 6.3

#> 3 3 F control 9.5

#> 4 4 M control 11.5

#> 5 1 M cond1 12.3

#> 6 2 F cond1 10.6

#> 7 3 F cond1 13.1

#> 8 4 M cond1 13.4

#> 9 1 M cond2 10.7

#> 10 2 F cond2 11.1

#> 11 3 F cond2 13.8

#> 12 4 M cond2 12.9

也可以靠列出每个列来

gather(olddata_wide, condition, measurement, control, cond1, cond2)

如果要以编程的形式来使用函数 gather() , 需要把列名包含进变量中

keycol <- "condition"

valuecol <- "measurement"

gathercols <- c("control", "cond1", "cond2")

gather_(olddata_wide, keycol, valuecol, gathercols)

扩展:重命名变量列的因子 level ,然后进行排序

# 重命名因子名字 "cond1" 、 "cond2" 到 "first" 、 "second"

levels(data_long$condition)[levels(data_long$condition)=="cond1"] <- "first"

levels(data_long$condition)[levels(data_long$condition)=="cond2"] <- "second"

# 先按 subject 排序, 再按 condition 排序

data_long <- data_long[order(data_long$subject, data_long$condition), ]

data_long

#> subject sex condition measurement

#> 1 1 M control 7.9

#> 5 1 M first 12.3

#> 9 1 M second 10.7

#> 2 2 F control 6.3

#> 6 2 F first 10.6

#> 10 2 F second 11.1

#> 3 3 F control 9.5

#> 7 3 F first 13.1

#> 11 3 F second 13.8

#> 4 4 M control 11.5

#> 8 4 M first 13.4

#> 12 4 M second 12.9

2、从长到宽

使用函数 spread() :

olddata_long

#> subject sex condition measurement

#> 1 1 M control 7.9

#> 2 1 M cond1 12.3

#> 3 1 M cond2 10.7

#> 4 2 F control 6.3

#> 5 2 F cond1 10.6

#> 6 2 F cond2 11.1

#> 7 3 F control 9.5

#> 8 3 F cond1 13.1

#> 9 3 F cond2 13.8

#> 10 4 M control 11.5

#> 11 4 M cond1 13.4

#> 12 4 M cond2 12.9

library(tidyr)

# The arguments to spread():

# - data: 数据集

# - key: 需要变成横向的列

# - value: 用于填充key列的数据来源

data_wide <- spread(olddata_long, condition, measurement)

## 将 condition 的几类拆成另外几列

data_wide

#> subject sex cond1 cond2 control

#> 1 1 M 12.3 10.7 7.9

#> 2 2 F 10.6 11.1 6.3

#> 3 3 F 13.1 13.8 9.5

#> 4 4 M 13.4 12.9 11.5

可以理解为 spread() 和 gather()是完全相反的

扩展:美化数据外观的举措

# R重命名cond1、cond2

names(data_wide)[names(data_wide)=="cond1"] <- "first"

names(data_wide)[names(data_wide)=="cond2"] <- "second"

# 重新排序列

data_wide <- data_wide[, c(1,2,5,3,4)]

data_wide

#> subject sex control first second

#> 1 1 M 7.9 12.3 10.7

#> 2 2 F 6.3 10.6 11.1

#> 3 3 F 9.5 13.1 13.8

#> 4 4 M 11.5 13.4 12.9

因子水平的顺序决定了列的顺序。 可以在重塑之前更改级别顺序,也可以在之后对列进行重新排序。

使用reshape2 包

1、从宽到长

melt()函数

olddata_wide

#> subject sex control cond1 cond2

#> 1 1 M 7.9 12.3 10.7

#> 2 2 F 6.3 10.6 11.1

#> 3 3 F 9.5 13.1 13.8

#> 4 4 M 11.5 13.4 12.9

library(reshape2)

# melt参数解释

melt(data, # 需要操作的数据

id.vars, # 不想改变的数据列

measure.vars, # 你要melt的数据

variable.name= 'variable', # melt操作后,为新列变量取名

na.rm=FALSE, # 是否去除NA

value.name='value', # 新列对应值的变量名

factorsAsStrings=TRUE)

melt(olddata_wide, id.vars=c("subject", "sex"))

#> subject sex variable value

#> 1 1 M control 7.9

#> 2 2 F control 6.3

#> 3 3 F control 9.5

#> 4 4 M control 11.5

#> 5 1 M cond1 12.3

#> 6 2 F cond1 10.6

#> 7 3 F cond1 13.1

#> 8 4 M cond1 13.4

#> 9 1 M cond2 10.7

#> 10 2 F cond2 11.1

#> 11 3 F cond2 13.8

#> 12 4 M cond2 12.9

# 更多输出参数设置

data_long <- melt(olddata_wide,

id.vars=c("subject", "sex"),

measure.vars=c("control", "cond1", "cond2" ),

variable.name="condition",

value.name="measurement"

)

data_long

#> subject sex condition measurement

#> 1 1 M control 7.9

#> 2 2 F control 6.3

#> 3 3 F control 9.5

#> 4 4 M control 11.5

#> 5 1 M cond1 12.3

#> 6 2 F cond1 10.6

#> 7 3 F cond1 13.1

#> 8 4 M cond1 13.4

#> 9 1 M cond2 10.7

#> 10 2 F cond2 11.1

#> 11 3 F cond2 13.8

#> 12 4 M cond2 12.9

如果省略 measure.vars , melt() 将自动使用所有其他变量作为 id.vars ; 如果省略 id.vars ,情况正好相反。

如果不指定 variable.name ,它将命名该列 “variable” ; 如果省略 value.name ,它将命名该列 “measurement” 。

扩展:重命名变量列的因子 level ,然后进行排序 (步骤同上)

2、从长到宽

cast() 函数分为:dcast() 、 acast() 用 dcast() 重构数据框;如果是列表或者是矩阵,改用 acast()

# dcast参数解释:

dcast(data, formula, fun.aggregate)

# - data : 所选的数据;

# - formula:描述了想要的最后结果; 其接受的公式形如:rowvar1 + rowvar2 + ... ~ colvar1 + colvar2 + ...;

## 在这一公式中,rowvar1 + rowvar2 + ...定义了要划掉的变量集合,以确定各行的内容,而colvar1 + colvar2 +

## ...则定义了要划掉的、确定各列内容的变量集合。

# - fun.aggregate是(可选的)数据整合函数,比如求均值等等。

olddata_long

#> subject sex condition measurement

#> 1 1 M control 7.9

#> 2 1 M cond1 12.3

#> 3 1 M cond2 10.7

#> 4 2 F control 6.3

#> 5 2 F cond1 10.6

#> 6 2 F cond2 11.1

#> 7 3 F control 9.5

#> 8 3 F cond1 13.1

#> 9 3 F cond2 13.8

#> 10 4 M control 11.5

#> 11 4 M cond1 13.4

#> 12 4 M cond2 12.9

# 保留 "subject" 和 "sex" 两列

# 拆分 condition 列为 control、cond1、cond2三个变量

# 拆分后的变量测量值用 measurement 来填充

library(reshape2)

data_wide <- dcast(olddata_long, subject + sex ~ condition, value.var="measurement")

data_wide

#> subject sex cond1 cond2 control

#> 1 1 M 12.3 10.7 7.9

#> 2 2 F 10.6 11.1 6.3

#> 3 3 F 13.1 13.8 9.5

#> 4 4 M 13.4 12.9 11.5

扩展:美化数据外观的举措 (同上)

好文阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。