我有一个包含四列的数据框,并希望将其转换为具有2列的数据框,但序列很重要(因此堆栈或合并而无需额外排序)
X1 Y1 X2 Y2
1 2 3 4
5 6 7 8
要
X1 Y1
1 2
3 4
5 6
7 8
我丑陋的版本:
nrow = 4
# Test data set
d = setNames(data.frame(matrix(sample(1:(nrow*4)), nrow=nrow)),
c("X1","Y1","X2","Y2"))d
# Create empty data frame
d1 = data.frame(matrix(rep(NA, nrow*2*2), nrow = nrow*2))
# Elements 1, 3, 5...
d1[seq(1, nrow*2, by = 2),] = d[,1:2]
# Elements 2, 4, 6...
d1[seq(2, nrow*2, by = 2),] = d[,3:4]
没必要基础R。
稍后补充:我刚刚找到:
data.frame(matrix(as.vector(t(as.matrix(d))), nrow = 2*nrow, byrow = TRUE))
但看起来像@akrun有一个稍微简单的版本
@alistaire提到的帖子中的替代解决方案,例如使用reshape
,绝对不比我的原始版本更优雅。
答案 0 :(得分:2)
如果' X'和' Y'列是交替的,然后,我们转置数据集,通过指定原始数据集的列数除以2并转换为matrix
data.frame
as.data.frame(matrix(t(df1), ncol= ncol(df1)/2, byrow=TRUE,
dimnames = list(NULL, c("X1", "Y1"))))
# X1 Y1
#1 1 2
#2 3 4
#3 5 6
#4 7 8
或者使用melt
中的data.table
,我们可以根据列名称选择多个measure
patterns
来转换为' long'格式
library(data.table)
melt(setDT(df1), measure = patterns("^X", "^Y"),
value.name = c("X1", "Y1"))[, variable := NULL][order(X1)]
# X1 Y1
#1: 1 2
#2: 3 4
#3: 5 6
#4: 7 8