重塑 R 中的数据(宽 -> 长)
Reshaping data in R (wide -> Long)
我想将 df1
转换为 df2
旧样本数据框df1
df1 <- structure(list(ID = 1:2, Group = c(1L, 1L),
M1a2hB = c(0.2, 0.3), M1a3hB = c(0.4, 0.6),
M2a2hB = c(0.3, 0.4), M2a3hB = c(0.6, 0.6),
M1r2hB = c(200L, 300L), M1r3hB = c(400L, 600L),
M2r2hB = c(300L, 400L), M2r3hB = c(600L, 600L)),
.Names = c("ID", "Group", "M1a2hB", "M1a3hB", "M2a2hB",
"M2a3hB","M1r2hB", "M1r3hB","M2r2hB", "M2r3hB"),
class = "data.frame", row.names = c(NA, -2L))
ID Group M1a2hB M1a3hB M2a2hB M2a3hB.... M1r2hB M1r3hB M2r2hB M2r3hB ...
1 1 0.2 0.4 0.3 0.6 ... 200 400 300 600 ...
2 1 0.3 0.6 0.4 0.6 ... 300 600 400 600 ...
此处,df1
有 100 个 ID 和 1100 个列。每个结果 measure 都有两列用于绝对变化,两列用于相对变化。有将近 270 个结果 m 措施。
M1a2hB
是第一次测量从时间 2 到基线的绝对变化,M1a3hB
是时间 3 到基线的绝对变化。类似地,M1r2hB
是第一个结果从时间 2 到基线的相对变化,M1r3hB
是结果从时间 3 到基线的相对变化。
新 df2
:
ID Group time M1a M2a ... M1r M2r ...
1 1 1 0.0 0.0 ... 000 000 ...
1 1 2 0.2 0.3 ... 200 300 ...
1 1 3 0.4 0.6 ... 400 600 ...
2 1 1 0.0 0.0 ... 000 000 ...
2 1 2 0.3 0.4 ... 300 400 ...
2 1 3 0.6 0.6 ... 600 600 ...
有什么建议吗?随时要求任何澄清。谢谢!期待!
p.s。我已经尝试 运行 以前帖子中的一些代码(如果有兴趣请看下面),但它们看起来不同,因为 df 是三维数据,而 df2 包含额外的时间列
In R, plotting wide form data with ggplot2 or base plot. Is there a way to use ggplot2 without melting wide form data frame?
Reshaping repeated measures data in R wide to long
我们可以使用 sub
从列名称中提取模式,split
使用 'nm1' 该向量的序列,将其用作 measure
in [=15] =] 从 'wide' 转换为 'long' 格式。
library(data.table)
nm1 <- sub("\d+[[:alpha:]]+$", '', names(df1)[-(1:2)])
lst <- split(seq_along(nm1)+2, nm1)
melt(setDT(df1), measure = lst,
value.name= names(lst), variable.name= 'time')[order(ID)]
# ID Group time M1a M1r M2a M2r
#1: 1 1 1 0.2 200 0.3 300
#2: 1 1 2 0.4 400 0.6 600
#3: 2 1 1 0.3 300 0.4 400
#4: 2 1 2 0.6 600 0.6 600
数据
df1 <- structure(list(ID = 1:2, Group = c(1L, 1L),
M1a2hB = c(0.2, 0.3
), M1a3hB = c(0.4, 0.6), M2a2hB = c(0.3, 0.4),
M2a3hB = c(0.6,
0.6), M1r2hB = c(200L, 300L), M1r3hB = c(400L, 600L),
M2r2hB = c(300L,
400L), M2r3hB = c(600L, 600L)), .Names = c("ID", "Group", "M1a2hB",
"M1a3hB", "M2a2hB", "M2a3hB", "M1r2hB", "M1r3hB",
"M2r2hB", "M2r3hB"
), class = "data.frame", row.names = c(NA, -2L))
这里是使用 tidyr 的答案:
library(dplyr)
library(tidyr)
library(rex)
string_interpretation =
rex(capture("M",
digits,
or("a", "r")),
capture(digits))
result =
df1 %>%
gather(string, value, -ID, -Group) %>%
extract(string, c("variable", "time"), string_interpretation) %>%
spread(variable, value)
内置 base::reshape
可以很好地做到这一点:
df1 <- structure(list(ID = 1:2, Group = c(1L, 1L),
M1a2hB = c(0.2, 0.3), M1a3hB = c(0.4, 0.6),
M2a2hB = c(0.3, 0.4), M2a3hB = c(0.6, 0.6),
M1r2hB = c(200L, 300L), M1r3hB = c(400L, 600L),
M2r2hB = c(300L, 400L), M2r3hB = c(600L, 600L)),
.Names = c("ID", "Group", "M1a2hB", "M1a3hB", "M2a2hB",
"M2a3hB","M1r2hB", "M1r3hB","M2r2hB", "M2r3hB"),
class = "data.frame", row.names = c(NA, -2L))
df1
# ID Group M1a2hB M1a3hB M2a2hB M2a3hB M1r2hB M1r3hB M2r2hB M2r3hB
# 1 1 0.2 0.4 0.3 0.6 200 400 300 600
# 2 1 0.3 0.6 0.4 0.6 300 600 400 600
df2 <- reshape(df1, varying=list(c(3,4),c(5,6),c(7,8),c(9,10)),
v.names=c("M1a", "M2a", "M1r", "M2r"),
timevar="time", times=2:3, direction="long")
df2
# ID Group time M1a M2a M1r M2r id
# 1 1 2 0.2 0.3 200 300 1
# 2 1 2 0.3 0.4 300 400 2
# 1 1 3 0.4 0.6 400 600 1
# 2 1 3 0.6 0.6 600 600 2
如果您在 m <- 2
个时间点(2 小时、3 小时)有 n <- 270
个测量值,请将 reshape
的参数更改为
varying=split(1:(n*m*2)+2,rep(1:(n*2), each=m)) # `*2` accounts for doubling by relative and absolute measurements.
# `+2` accounts for the `ID` and `Group` columns at the beginning
v.names=c(paste0("M", 1:n, "a"), paste0("M", 1:n, "r"))
我假设 time==1
在您的示例中 df2
指的是基线测量值,而不是未提及的 1h
,因为它们似乎全为零。为清楚起见,我将基线显示为 time==0
。 使基线显示在 df2
中的一种 方法是将零值基线测量值添加到 df1
。
n <- 2 # use n <- 270 for 270 outcomes, measured at each time point, reported both in absolute and relative terms
df1.5 <- data.frame(df1,
setNames(as.list(rep(0,2*n)), c(paste0("M", 1:n, "a0hB"), paste0("M", 1:n, "r0hB"))))
df2 <- reshape(df1.5, varying=split(1:(n*3*2)+2, c(rep(1:(n*2), each=2), 1:(n*2))),
v.names=c(paste0("M", 1:n, "a"), paste0("M", 1:n, "r")),
timevar="time", idvar=c("Group", "ID"), times=c(2,3,0), direction="long")
# ID Group time M1a M2a M1r M2r
# 1 1 2 0.2 0.3 200 300
# 2 1 2 0.3 0.4 300 400
# 1 1 3 0.4 0.6 400 600
# 2 1 3 0.6 0.6 600 600
# 1 1 0 0.0 0.0 0 0
# 2 1 0 0.0 0.0 0 0
然后排序。
df2.sorted <- df2[order(df2$Group, df2$ID, df2$time),]
你可以用我的r包onetree,已经上传到我的github yikeshu0611.
install.packages("devtools") #if you didnot have devtools packages in r
library(devtools)
install_github("yikeshu0611/onetree") #install onetree package from github
1。一步一步
首先教大家一步步把宽转长。
library(onetree)
long1=reshape_toLong(data=df1,
id= "ID",
j="newcolumn",
value.var.prefix=c("M1a","M2a","M1r","M2r")
在此命令中,j 是新列的名称。
你会得到 long1 下面的结果
long1
ID Group newcolumn M1a M2a M1r M2r
1 1 2hB 0.2 0.3 200 300
1 1 3hB 0.4 0.6 400 600
2 1 2hB 0.3 0.4 300 400
2 1 3hB 0.6 0.6 600 600
另外,我们在数据中可以看到long1,M1a,M2a------,M1r,M2r-----。该数据仍然是宽数据。我们仍然可以将它转换为 long。我们使用 M1、M2 作为前缀。 a 和 r 作为新列,这是测试方式。命令如下。
long2=reshape_toLong(data = long1,
id = c("ID","newcolumn"),
j = "testway",
value.var.prefix = c("M1","M2"))
long2
ID newcolumn Group testway M1 M2
1 1 2hB 1 a 0.2 0.3
2 1 2hB 1 r 200.0 300.0
3 1 3hB 1 a 0.4 0.6
4 1 3hB 1 r 400.0 600.0
5 2 2hB 1 a 0.3 0.4
6 2 2hB 1 r 300.0 400.0
7 2 3hB 1 a 0.6 0.6
8 2 3hB 1 r 600.0 600.0
这里,我们使用两个变量ID和newcolumn作为id对象。因为在长数据中,id被当作一个唯一的变量,如果我们只用id,就会出现mismatch。您也可以创建一个新 ID,例如:idnew.
long1$idnew = 1:nrow(long1)
reshape_toLong(data = long1,
id = "idnew",
j = "testway",
value.var.prefix = c("M1","M2"))
让我们继续!在数据long2中,可能有M1,M2,--------。所以long2还是宽数据。是的,我们可以更改为长数据。 M 作为前缀,1,2,3,-----作为新列。但是,id应该是ID,newcolumn和testway,或者你可以创建一个新的id到long2,这将确保id唯一。
long3=reshape_toLong(data = long2,
id = c("ID","newcolumn","testway"),
j = "testnumber",
value.var.prefix = "M")
long3
ID newcolumn testway Group testnumber M
1 1 2hB a 1 1 0.2
2 1 2hB a 1 2 0.3
3 1 2hB r 1 1 200.0
4 1 2hB r 1 2 300.0
5 1 3hB a 1 1 0.4
6 1 3hB a 1 2 0.6
7 1 3hB r 1 1 400.0
8 1 3hB r 1 2 600.0
9 2 2hB a 1 1 0.3
10 2 2hB a 1 2 0.4
11 2 2hB r 1 1 300.0
12 2 2hB r 1 2 400.0
13 2 3hB a 1 1 0.6
14 2 3hB a 1 2 0.6
15 2 3hB r 1 1 600.0
16 2 3hB r 1 2 600.0
现在数据long3是一个绝对长的数据。
前缀很重要,我们使用如下前缀
- 第一个:M1a、M2a、M1r、M2r
- 第二个:M1、M2
- 第三名:M
我们更改 id 三次,使其唯一
- 第一个:ID
- 第二个:ID,新列
- 第三个:ID,新列,testway
j 是新列
- 第一个:新列
- 第二个:测试
- 第三名:测试人数
2。快一点
如果每个测量结果有 4 个结果:a2、a3、r2 r3。 a:绝对值,r:相对值,2:时间 2,3:时间 3。然后 1100 列有 275 个测量结果 (1100/4)。因此,我们有 M1a2hB、M2a2hB、M3a2hB------M275a2hB。和M1a3hB,M2a3hB,M3a3hB------M275a3hB,M3就是这样。如果我们使用这样的命令,我们将有一个很长的value.var.prefix。
但是,我们可以使用 paste0 函数使用更快的方式构造前缀。
ma2=paste0("M",1:275,"a")
ma3=paste0("M",1:275,"a")
mr2=paste0("M",1:275,"r")
mr3=paste0("M",1:275,"r")
m=c(ma2,ma3,mr2,mr3)
在df1中,我们只有2个测量结果,所以我们可以使用下面的命令
ma2=paste0("M",1:2,"a")
ma3=paste0("M",1:2,"a")
mr2=paste0("M",1:2,"r")
mr3=paste0("M",1:2,"r")
prefix=c(ma2,ma3,mr2,mr3)
reshape_toLong(data = df1,
id = "ID",
j = "newcolumn",
value.var.prefix = prefix)
ID Group newcolumn M1a M2a M1r M2r
1 1 1 2hB 0.2 0.3 200 300
2 1 1 3hB 0.4 0.6 400 600
3 2 1 2hB 0.3 0.4 300 400
4 2 1 3hB 0.6 0.6 600 600
仍然,我们可以使用 M1,M2----- 作为前缀,我们将 a2hB,a3hB,r2hB,r3hB 更改为新列。然后我们将新列子串到不同的列。
m1=paste0("M",1:2)
m2=paste0("M",1:2)
prefix=c(m1,m2)
long4=reshape_toLong(data = df1,
id = "ID",
j = "newcolumn",
value.var.prefix = prefix)
long4
ID Group newcolumn M1 M2
1 1 1 a2hB 0.2 0.3
2 1 1 a3hB 0.4 0.6
3 1 1 r2hB 200.0 300.0
4 1 1 r3hB 400.0 600.0
5 2 1 a2hB 0.3 0.4
6 2 1 a3hB 0.6 0.6
7 2 1 r2hB 300.0 400.0
8 2 1 r3hB 600.0 600.0
long4$testway=Left(long4$newcolumn,1)
long4$time=Right(long4$newcolumn,3)
long4
ID Group newcolumn M1 M2 testway time
1 1 1 a2hB 0.2 0.3 a 2hB
2 1 1 a3hB 0.4 0.6 a 3hB
3 1 1 r2hB 200.0 300.0 r 2hB
4 1 1 r3hB 400.0 600.0 r 3hB
5 2 1 a2hB 0.3 0.4 a 2hB
6 2 1 a3hB 0.6 0.6 a 3hB
7 2 1 r2hB 300.0 400.0 r 2hB
8 2 1 r3hB 600.0 600.0 r 3hB
最后,我们只能使用M作为前缀,来获取绝对数据。
long5=reshape_toLong(data = df1,
id = "ID",
j = "newcolumn",
value.var.prefix = "M")
long5
ID Group newcolumn M
1 1 1 1a2hB 0.2
2 1 1 1a3hB 0.4
3 1 1 2a2hB 0.3
4 1 1 2a3hB 0.6
5 1 1 1r2hB 200.0
6 1 1 1r3hB 400.0
7 1 1 2r2hB 300.0
8 1 1 2r3hB 600.0
9 2 1 1a2hB 0.3
10 2 1 1a3hB 0.6
11 2 1 2a2hB 0.4
12 2 1 2a3hB 0.6
13 2 1 1r2hB 300.0
14 2 1 1r3hB 600.0
15 2 1 2r2hB 400.0
16 2 1 2r3hB 600.0
然后我们可以使用onetree包中的Left、Mid和Right函数从left、mid和right中提取新的列。
long5$testnumber=Left(long5$newcolumn,1)
long5$testway=Mid(long5$newcolumn,2,1)
long5$time=Right(long5$newcolumn,3)
long5
ID Group newcolumn M testnumber testway time
1 1 1 1a2hB 0.2 1 a 2hB
2 1 1 1a3hB 0.4 1 a 3hB
3 1 1 2a2hB 0.3 2 a 2hB
4 1 1 2a3hB 0.6 2 a 3hB
5 1 1 1r2hB 200.0 1 r 2hB
6 1 1 1r3hB 400.0 1 r 3hB
7 1 1 2r2hB 300.0 2 r 2hB
8 1 1 2r3hB 600.0 2 r 3hB
9 2 1 1a2hB 0.3 1 a 2hB
10 2 1 1a3hB 0.6 1 a 3hB
11 2 1 2a2hB 0.4 2 a 2hB
12 2 1 2a3hB 0.6 2 a 3hB
13 2 1 1r2hB 300.0 1 r 2hB
14 2 1 1r3hB 600.0 1 r 3hB
15 2 1 2r2hB 400.0 2 r 2hB
16 2 1 2r3hB 600.0 2 r 3hB
这里,我们使用不同的前缀来获取不同的数据。
- 首先:使用paste0函数构造
- 第二个:M1、M2、M3------,仍然是paste0功能,但更简单
- 第三:我们只用M
- 我们没有更改 id 和 j
3。结论
在reshape_toLong函数中:
- data: 是你要转换的数据
- id:是唯一id变量,可以是一个变量,也可以是多个
- j: 是新变量name,你要堆叠time或sequence number[=106] =]
- value.var.prefix: 是值变量
的前缀
我想将 df1
转换为 df2
旧样本数据框df1
df1 <- structure(list(ID = 1:2, Group = c(1L, 1L),
M1a2hB = c(0.2, 0.3), M1a3hB = c(0.4, 0.6),
M2a2hB = c(0.3, 0.4), M2a3hB = c(0.6, 0.6),
M1r2hB = c(200L, 300L), M1r3hB = c(400L, 600L),
M2r2hB = c(300L, 400L), M2r3hB = c(600L, 600L)),
.Names = c("ID", "Group", "M1a2hB", "M1a3hB", "M2a2hB",
"M2a3hB","M1r2hB", "M1r3hB","M2r2hB", "M2r3hB"),
class = "data.frame", row.names = c(NA, -2L))
ID Group M1a2hB M1a3hB M2a2hB M2a3hB.... M1r2hB M1r3hB M2r2hB M2r3hB ...
1 1 0.2 0.4 0.3 0.6 ... 200 400 300 600 ...
2 1 0.3 0.6 0.4 0.6 ... 300 600 400 600 ...
此处,df1
有 100 个 ID 和 1100 个列。每个结果 measure 都有两列用于绝对变化,两列用于相对变化。有将近 270 个结果 m 措施。
M1a2hB
是第一次测量从时间 2 到基线的绝对变化,M1a3hB
是时间 3 到基线的绝对变化。类似地,M1r2hB
是第一个结果从时间 2 到基线的相对变化,M1r3hB
是结果从时间 3 到基线的相对变化。
新 df2
:
ID Group time M1a M2a ... M1r M2r ...
1 1 1 0.0 0.0 ... 000 000 ...
1 1 2 0.2 0.3 ... 200 300 ...
1 1 3 0.4 0.6 ... 400 600 ...
2 1 1 0.0 0.0 ... 000 000 ...
2 1 2 0.3 0.4 ... 300 400 ...
2 1 3 0.6 0.6 ... 600 600 ...
有什么建议吗?随时要求任何澄清。谢谢!期待!
p.s。我已经尝试 运行 以前帖子中的一些代码(如果有兴趣请看下面),但它们看起来不同,因为 df 是三维数据,而 df2 包含额外的时间列
In R, plotting wide form data with ggplot2 or base plot. Is there a way to use ggplot2 without melting wide form data frame?
Reshaping repeated measures data in R wide to long
我们可以使用 sub
从列名称中提取模式,split
使用 'nm1' 该向量的序列,将其用作 measure
in [=15] =] 从 'wide' 转换为 'long' 格式。
library(data.table)
nm1 <- sub("\d+[[:alpha:]]+$", '', names(df1)[-(1:2)])
lst <- split(seq_along(nm1)+2, nm1)
melt(setDT(df1), measure = lst,
value.name= names(lst), variable.name= 'time')[order(ID)]
# ID Group time M1a M1r M2a M2r
#1: 1 1 1 0.2 200 0.3 300
#2: 1 1 2 0.4 400 0.6 600
#3: 2 1 1 0.3 300 0.4 400
#4: 2 1 2 0.6 600 0.6 600
数据
df1 <- structure(list(ID = 1:2, Group = c(1L, 1L),
M1a2hB = c(0.2, 0.3
), M1a3hB = c(0.4, 0.6), M2a2hB = c(0.3, 0.4),
M2a3hB = c(0.6,
0.6), M1r2hB = c(200L, 300L), M1r3hB = c(400L, 600L),
M2r2hB = c(300L,
400L), M2r3hB = c(600L, 600L)), .Names = c("ID", "Group", "M1a2hB",
"M1a3hB", "M2a2hB", "M2a3hB", "M1r2hB", "M1r3hB",
"M2r2hB", "M2r3hB"
), class = "data.frame", row.names = c(NA, -2L))
这里是使用 tidyr 的答案:
library(dplyr)
library(tidyr)
library(rex)
string_interpretation =
rex(capture("M",
digits,
or("a", "r")),
capture(digits))
result =
df1 %>%
gather(string, value, -ID, -Group) %>%
extract(string, c("variable", "time"), string_interpretation) %>%
spread(variable, value)
内置 base::reshape
可以很好地做到这一点:
df1 <- structure(list(ID = 1:2, Group = c(1L, 1L),
M1a2hB = c(0.2, 0.3), M1a3hB = c(0.4, 0.6),
M2a2hB = c(0.3, 0.4), M2a3hB = c(0.6, 0.6),
M1r2hB = c(200L, 300L), M1r3hB = c(400L, 600L),
M2r2hB = c(300L, 400L), M2r3hB = c(600L, 600L)),
.Names = c("ID", "Group", "M1a2hB", "M1a3hB", "M2a2hB",
"M2a3hB","M1r2hB", "M1r3hB","M2r2hB", "M2r3hB"),
class = "data.frame", row.names = c(NA, -2L))
df1
# ID Group M1a2hB M1a3hB M2a2hB M2a3hB M1r2hB M1r3hB M2r2hB M2r3hB
# 1 1 0.2 0.4 0.3 0.6 200 400 300 600
# 2 1 0.3 0.6 0.4 0.6 300 600 400 600
df2 <- reshape(df1, varying=list(c(3,4),c(5,6),c(7,8),c(9,10)),
v.names=c("M1a", "M2a", "M1r", "M2r"),
timevar="time", times=2:3, direction="long")
df2
# ID Group time M1a M2a M1r M2r id
# 1 1 2 0.2 0.3 200 300 1
# 2 1 2 0.3 0.4 300 400 2
# 1 1 3 0.4 0.6 400 600 1
# 2 1 3 0.6 0.6 600 600 2
如果您在 m <- 2
个时间点(2 小时、3 小时)有 n <- 270
个测量值,请将 reshape
的参数更改为
varying=split(1:(n*m*2)+2,rep(1:(n*2), each=m)) # `*2` accounts for doubling by relative and absolute measurements.
# `+2` accounts for the `ID` and `Group` columns at the beginning
v.names=c(paste0("M", 1:n, "a"), paste0("M", 1:n, "r"))
我假设 time==1
在您的示例中 df2
指的是基线测量值,而不是未提及的 1h
,因为它们似乎全为零。为清楚起见,我将基线显示为 time==0
。 使基线显示在 df2
中的一种 方法是将零值基线测量值添加到 df1
。
n <- 2 # use n <- 270 for 270 outcomes, measured at each time point, reported both in absolute and relative terms
df1.5 <- data.frame(df1,
setNames(as.list(rep(0,2*n)), c(paste0("M", 1:n, "a0hB"), paste0("M", 1:n, "r0hB"))))
df2 <- reshape(df1.5, varying=split(1:(n*3*2)+2, c(rep(1:(n*2), each=2), 1:(n*2))),
v.names=c(paste0("M", 1:n, "a"), paste0("M", 1:n, "r")),
timevar="time", idvar=c("Group", "ID"), times=c(2,3,0), direction="long")
# ID Group time M1a M2a M1r M2r
# 1 1 2 0.2 0.3 200 300
# 2 1 2 0.3 0.4 300 400
# 1 1 3 0.4 0.6 400 600
# 2 1 3 0.6 0.6 600 600
# 1 1 0 0.0 0.0 0 0
# 2 1 0 0.0 0.0 0 0
然后排序。
df2.sorted <- df2[order(df2$Group, df2$ID, df2$time),]
你可以用我的r包onetree,已经上传到我的github yikeshu0611.
install.packages("devtools") #if you didnot have devtools packages in r
library(devtools)
install_github("yikeshu0611/onetree") #install onetree package from github
1。一步一步
首先教大家一步步把宽转长。
library(onetree)
long1=reshape_toLong(data=df1,
id= "ID",
j="newcolumn",
value.var.prefix=c("M1a","M2a","M1r","M2r")
在此命令中,j 是新列的名称。 你会得到 long1 下面的结果
long1
ID Group newcolumn M1a M2a M1r M2r
1 1 2hB 0.2 0.3 200 300
1 1 3hB 0.4 0.6 400 600
2 1 2hB 0.3 0.4 300 400
2 1 3hB 0.6 0.6 600 600
另外,我们在数据中可以看到long1,M1a,M2a------,M1r,M2r-----。该数据仍然是宽数据。我们仍然可以将它转换为 long。我们使用 M1、M2 作为前缀。 a 和 r 作为新列,这是测试方式。命令如下。
long2=reshape_toLong(data = long1,
id = c("ID","newcolumn"),
j = "testway",
value.var.prefix = c("M1","M2"))
long2
ID newcolumn Group testway M1 M2
1 1 2hB 1 a 0.2 0.3
2 1 2hB 1 r 200.0 300.0
3 1 3hB 1 a 0.4 0.6
4 1 3hB 1 r 400.0 600.0
5 2 2hB 1 a 0.3 0.4
6 2 2hB 1 r 300.0 400.0
7 2 3hB 1 a 0.6 0.6
8 2 3hB 1 r 600.0 600.0
这里,我们使用两个变量ID和newcolumn作为id对象。因为在长数据中,id被当作一个唯一的变量,如果我们只用id,就会出现mismatch。您也可以创建一个新 ID,例如:idnew.
long1$idnew = 1:nrow(long1)
reshape_toLong(data = long1,
id = "idnew",
j = "testway",
value.var.prefix = c("M1","M2"))
让我们继续!在数据long2中,可能有M1,M2,--------。所以long2还是宽数据。是的,我们可以更改为长数据。 M 作为前缀,1,2,3,-----作为新列。但是,id应该是ID,newcolumn和testway,或者你可以创建一个新的id到long2,这将确保id唯一。
long3=reshape_toLong(data = long2,
id = c("ID","newcolumn","testway"),
j = "testnumber",
value.var.prefix = "M")
long3
ID newcolumn testway Group testnumber M
1 1 2hB a 1 1 0.2
2 1 2hB a 1 2 0.3
3 1 2hB r 1 1 200.0
4 1 2hB r 1 2 300.0
5 1 3hB a 1 1 0.4
6 1 3hB a 1 2 0.6
7 1 3hB r 1 1 400.0
8 1 3hB r 1 2 600.0
9 2 2hB a 1 1 0.3
10 2 2hB a 1 2 0.4
11 2 2hB r 1 1 300.0
12 2 2hB r 1 2 400.0
13 2 3hB a 1 1 0.6
14 2 3hB a 1 2 0.6
15 2 3hB r 1 1 600.0
16 2 3hB r 1 2 600.0
现在数据long3是一个绝对长的数据。
前缀很重要,我们使用如下前缀
- 第一个:M1a、M2a、M1r、M2r
- 第二个:M1、M2
- 第三名:M
我们更改 id 三次,使其唯一
- 第一个:ID
- 第二个:ID,新列
- 第三个:ID,新列,testway
j 是新列
- 第一个:新列
- 第二个:测试
- 第三名:测试人数
2。快一点
如果每个测量结果有 4 个结果:a2、a3、r2 r3。 a:绝对值,r:相对值,2:时间 2,3:时间 3。然后 1100 列有 275 个测量结果 (1100/4)。因此,我们有 M1a2hB、M2a2hB、M3a2hB------M275a2hB。和M1a3hB,M2a3hB,M3a3hB------M275a3hB,M3就是这样。如果我们使用这样的命令,我们将有一个很长的value.var.prefix。 但是,我们可以使用 paste0 函数使用更快的方式构造前缀。
ma2=paste0("M",1:275,"a")
ma3=paste0("M",1:275,"a")
mr2=paste0("M",1:275,"r")
mr3=paste0("M",1:275,"r")
m=c(ma2,ma3,mr2,mr3)
在df1中,我们只有2个测量结果,所以我们可以使用下面的命令
ma2=paste0("M",1:2,"a")
ma3=paste0("M",1:2,"a")
mr2=paste0("M",1:2,"r")
mr3=paste0("M",1:2,"r")
prefix=c(ma2,ma3,mr2,mr3)
reshape_toLong(data = df1,
id = "ID",
j = "newcolumn",
value.var.prefix = prefix)
ID Group newcolumn M1a M2a M1r M2r
1 1 1 2hB 0.2 0.3 200 300
2 1 1 3hB 0.4 0.6 400 600
3 2 1 2hB 0.3 0.4 300 400
4 2 1 3hB 0.6 0.6 600 600
仍然,我们可以使用 M1,M2----- 作为前缀,我们将 a2hB,a3hB,r2hB,r3hB 更改为新列。然后我们将新列子串到不同的列。
m1=paste0("M",1:2)
m2=paste0("M",1:2)
prefix=c(m1,m2)
long4=reshape_toLong(data = df1,
id = "ID",
j = "newcolumn",
value.var.prefix = prefix)
long4
ID Group newcolumn M1 M2
1 1 1 a2hB 0.2 0.3
2 1 1 a3hB 0.4 0.6
3 1 1 r2hB 200.0 300.0
4 1 1 r3hB 400.0 600.0
5 2 1 a2hB 0.3 0.4
6 2 1 a3hB 0.6 0.6
7 2 1 r2hB 300.0 400.0
8 2 1 r3hB 600.0 600.0
long4$testway=Left(long4$newcolumn,1)
long4$time=Right(long4$newcolumn,3)
long4
ID Group newcolumn M1 M2 testway time
1 1 1 a2hB 0.2 0.3 a 2hB
2 1 1 a3hB 0.4 0.6 a 3hB
3 1 1 r2hB 200.0 300.0 r 2hB
4 1 1 r3hB 400.0 600.0 r 3hB
5 2 1 a2hB 0.3 0.4 a 2hB
6 2 1 a3hB 0.6 0.6 a 3hB
7 2 1 r2hB 300.0 400.0 r 2hB
8 2 1 r3hB 600.0 600.0 r 3hB
最后,我们只能使用M作为前缀,来获取绝对数据。
long5=reshape_toLong(data = df1,
id = "ID",
j = "newcolumn",
value.var.prefix = "M")
long5
ID Group newcolumn M
1 1 1 1a2hB 0.2
2 1 1 1a3hB 0.4
3 1 1 2a2hB 0.3
4 1 1 2a3hB 0.6
5 1 1 1r2hB 200.0
6 1 1 1r3hB 400.0
7 1 1 2r2hB 300.0
8 1 1 2r3hB 600.0
9 2 1 1a2hB 0.3
10 2 1 1a3hB 0.6
11 2 1 2a2hB 0.4
12 2 1 2a3hB 0.6
13 2 1 1r2hB 300.0
14 2 1 1r3hB 600.0
15 2 1 2r2hB 400.0
16 2 1 2r3hB 600.0
然后我们可以使用onetree包中的Left、Mid和Right函数从left、mid和right中提取新的列。
long5$testnumber=Left(long5$newcolumn,1)
long5$testway=Mid(long5$newcolumn,2,1)
long5$time=Right(long5$newcolumn,3)
long5
ID Group newcolumn M testnumber testway time
1 1 1 1a2hB 0.2 1 a 2hB
2 1 1 1a3hB 0.4 1 a 3hB
3 1 1 2a2hB 0.3 2 a 2hB
4 1 1 2a3hB 0.6 2 a 3hB
5 1 1 1r2hB 200.0 1 r 2hB
6 1 1 1r3hB 400.0 1 r 3hB
7 1 1 2r2hB 300.0 2 r 2hB
8 1 1 2r3hB 600.0 2 r 3hB
9 2 1 1a2hB 0.3 1 a 2hB
10 2 1 1a3hB 0.6 1 a 3hB
11 2 1 2a2hB 0.4 2 a 2hB
12 2 1 2a3hB 0.6 2 a 3hB
13 2 1 1r2hB 300.0 1 r 2hB
14 2 1 1r3hB 600.0 1 r 3hB
15 2 1 2r2hB 400.0 2 r 2hB
16 2 1 2r3hB 600.0 2 r 3hB
这里,我们使用不同的前缀来获取不同的数据。
- 首先:使用paste0函数构造
- 第二个:M1、M2、M3------,仍然是paste0功能,但更简单
- 第三:我们只用M
- 我们没有更改 id 和 j
3。结论
在reshape_toLong函数中:
- data: 是你要转换的数据
- id:是唯一id变量,可以是一个变量,也可以是多个
- j: 是新变量name,你要堆叠time或sequence number[=106] =]
- value.var.prefix: 是值变量 的前缀