将数据从宽数据转换为长数据(使用多列)
Converting data from wide to long (using multiple columns)
我目前有与此类似的广泛数据:
cid dyad f1 f2 op1 op2 ed1 ed2 junk
1 2 0 0 2 4 5 7 0.876
1 5 0 1 2 4 4 3 0.765
等等
我希望进入一个类似于此的长数据框:
cid dyad f op ed junk id
1 2 0 2 5 0.876 1
1 2 0 4 7 0.876 2
1 5 0 2 4 0.765 1
1 5 1 4 3 0.765 2
我尝试过使用 gather() 函数和 reshape() 函数,但不知道如何创建多列而不是将所有列折叠成一个长样式
感谢所有帮助
tidyr 包可以使用函数 gather、separate 和 spread 解决这个问题:
df<-read.table(header=TRUE, text="cid dyad f1 f2 op1 op2 ed1 ed2 junk
1 2 0 0 2 4 5 7 0.876
1 5 0 1 2 4 4 3 0.765")
library(tidyr)
print(df %>%gather( name, value, -c(cid, dyad, junk)) %>%
separate( name, into=c("name", "id"), sep= -2 ) %>%
spread( key=c(name), value)
)
#step by step:
#collect the columns f, op, ed to the common cid, dyad and junk
df<-gather(df, name, value, -c(cid, dyad, junk))
#separate the number id from the names
df<-separate(df, name, into=c("name", "id"), sep= -2 )
#made wide again.
df<-spread(df, key=c(name), value)
您可以使用基础 reshape()
函数(大致)同时融合多组变量,方法是使用 varying
参数并将 direction
设置为 "long"
.
例如,您向 varying
参数提供了一个包含三个 "sets"(向量)变量名称的列表:
dat <- read.table(text="
cid dyad f1 f2 op1 op2 ed1 ed2 junk
1 2 0 0 2 4 5 7 0.876
1 5 0 1 2 4 4 3 0.765
", header=TRUE)
reshape(dat, direction="long",
varying=list(c("f1","f2"), c("op1","op2"), c("ed1","ed2")),
v.names=c("f","op","ed"))
你会得到这样的结果:
cid dyad junk time f op ed id
1.1 1 2 0.876 1 0 2 5 1
2.1 1 5 0.765 1 0 2 4 2
1.2 1 2 0.876 2 0 4 7 1
2.2 1 5 0.765 2 1 4 3 2
请注意,除了折叠的三个集合之外,还创建了两个变量:一个 $id
变量——它跟踪原始 table (dat
) 中的行号,和一个 $time
变量——对应于折叠的原始变量的顺序。现在还有嵌套的行号 -- 1.1, 2.1, 1.2, 2.2
,这里分别是该行的 $id
和 $time
的值。
在不知道您要跟踪的确切内容的情况下,很难说 $id
或 $time
是您想要用作行标识符的内容,但它们都在那里。
使用参数 timevar
和 idvar
可能也很有用(例如,您可以将 timevar
设置为 NULL
)。
reshape(dat, direction="long",
varying=list(c("f1","f2"), c("op1","op2"), c("ed1","ed2")),
v.names=c("f","op","ed"),
timevar="id1", idvar="id2")
我目前有与此类似的广泛数据:
cid dyad f1 f2 op1 op2 ed1 ed2 junk
1 2 0 0 2 4 5 7 0.876
1 5 0 1 2 4 4 3 0.765
等等
我希望进入一个类似于此的长数据框:
cid dyad f op ed junk id
1 2 0 2 5 0.876 1
1 2 0 4 7 0.876 2
1 5 0 2 4 0.765 1
1 5 1 4 3 0.765 2
我尝试过使用 gather() 函数和 reshape() 函数,但不知道如何创建多列而不是将所有列折叠成一个长样式
感谢所有帮助
tidyr 包可以使用函数 gather、separate 和 spread 解决这个问题:
df<-read.table(header=TRUE, text="cid dyad f1 f2 op1 op2 ed1 ed2 junk
1 2 0 0 2 4 5 7 0.876
1 5 0 1 2 4 4 3 0.765")
library(tidyr)
print(df %>%gather( name, value, -c(cid, dyad, junk)) %>%
separate( name, into=c("name", "id"), sep= -2 ) %>%
spread( key=c(name), value)
)
#step by step:
#collect the columns f, op, ed to the common cid, dyad and junk
df<-gather(df, name, value, -c(cid, dyad, junk))
#separate the number id from the names
df<-separate(df, name, into=c("name", "id"), sep= -2 )
#made wide again.
df<-spread(df, key=c(name), value)
您可以使用基础 reshape()
函数(大致)同时融合多组变量,方法是使用 varying
参数并将 direction
设置为 "long"
.
例如,您向 varying
参数提供了一个包含三个 "sets"(向量)变量名称的列表:
dat <- read.table(text="
cid dyad f1 f2 op1 op2 ed1 ed2 junk
1 2 0 0 2 4 5 7 0.876
1 5 0 1 2 4 4 3 0.765
", header=TRUE)
reshape(dat, direction="long",
varying=list(c("f1","f2"), c("op1","op2"), c("ed1","ed2")),
v.names=c("f","op","ed"))
你会得到这样的结果:
cid dyad junk time f op ed id
1.1 1 2 0.876 1 0 2 5 1
2.1 1 5 0.765 1 0 2 4 2
1.2 1 2 0.876 2 0 4 7 1
2.2 1 5 0.765 2 1 4 3 2
请注意,除了折叠的三个集合之外,还创建了两个变量:一个 $id
变量——它跟踪原始 table (dat
) 中的行号,和一个 $time
变量——对应于折叠的原始变量的顺序。现在还有嵌套的行号 -- 1.1, 2.1, 1.2, 2.2
,这里分别是该行的 $id
和 $time
的值。
在不知道您要跟踪的确切内容的情况下,很难说 $id
或 $time
是您想要用作行标识符的内容,但它们都在那里。
使用参数 timevar
和 idvar
可能也很有用(例如,您可以将 timevar
设置为 NULL
)。
reshape(dat, direction="long",
varying=list(c("f1","f2"), c("op1","op2"), c("ed1","ed2")),
v.names=c("f","op","ed"),
timevar="id1", idvar="id2")