[R重塑,由大块
我想重塑一个数据帧重组数据帧:[R重塑,由大块
目前,它看起来像这样:
ID | Gender |A1 | A2 | A3 | B1 | B2 | B3
ID_1 | m | 3 | 3 | 3 | 2 | 3 | 2
ID_2 | f | 1 | 1 | 1 | 4 | 4 | 4
我想有这样的:
ID | Gender | A1 | A2 | A3
ID_1 | m | 3 | 3 | 3 <- this would be columns A1 - A3 for ID 1
ID_1 | m | 2 | 2 | 2 <- this would be columns B1 - B3 for ID 1
ID_2 | f | 1 | 1 | 1 <- this would be columns A1 - A3 for ID 2
ID_2 | f | 4 | 4 | 4 <- this would be columns B1 - B3 for ID 2
( A1和B1/A2和B2是相同的变量(关于内容),例如:A1和B1将是测试1结果的变量,A2和B2都包含测试2的结果。因此,在为了评估使用它我需要一列中的Test1的结果和另一列中的所有Test2的结果。 我试图用“融化”来解决这个问题,但它只能将数据框一个接一个地融化,而不是大块。 (因为我需要保持前2列的方式,只重新排列最后4列,但作为三个块) 任何其他想法?谢谢!
一个衬垫使用reshape
从基地R.
reshape(dat, varying = 3:8, idvar = 1:2, direction = 'long', drop=FALSE,
timevar = 'Test')
ID Gender Test Test1 Test2 Test3
ID_1.m.A ID_1 m A A1 A2 A3
ID_2.f.A ID_2 f A A1 A2 A3
ID_1.m.B ID_1 m B B1 B2 B3
ID_2.f.B ID_2 f B B1 B2 B3
+1 - 很难打败这个解决方案。任何人都知道如何(在一行内)放弃那些丑陋的'row.names'? –
你可以通过添加一个参数'new.row.names = 1:4'来删除'row.name'。如果你不想硬编码4,你可以很容易地找出如何基于数据计算它。 – Ramnath
这个计算是我无法/无法弄清楚的。很好 - 即使是双线,这非常好。 –
正如@Andrie所说,第一步就是用给定的列(ID和性别)来融合数据。正如你所说,你的问题是确定哪些列然后“走到一起”。这里有一种方法,最初将这些信息编码成列名,然后从那里拉出来。
首先是一些虚拟数据
dat <- data.frame(ID=c("ID_1", "ID_2"), Gender=c("m","f"),
Test1.A = "A1", Test2.A = "A2", Test3.A = "A3",
Test1.B = "B1", Test2.B = "B2", Test3.B = "B3", stringsAsFactors=FALSE)
请注意,我已经与系统指示哪些测试和基时,一部分的名字命名的列。
> dat
ID Gender Test1.A Test2.A Test3.A Test1.B Test2.B Test3.B
1 ID_1 m A1 A2 A3 B1 B2 B3
2 ID_2 f A1 A2 A3 B1 B2 B3
使用reshape2
包
library("reshape2")
熔体中的数据,再取variable
柱,其具有的两个信息在它(测试和组),和分割信息的这两个比特到两个单独的列。
dat.m <- melt(dat, id.vars=c("ID", "Gender"))
dat.m <- cbind(dat.m, colsplit(dat.m$variable, "\\.", names=c("Test", "Group")))
现在很容易投射,因为测试和组是分开的。
dcast(dat.m, ID+Gender+Group~Test)
其中给出
> dcast(dat.m, ID+Gender+Group~Test)
ID Gender Group Test1 Test2 Test3
1 ID_1 m A A1 A2 A3
2 ID_1 m B B1 B2 B3
3 ID_2 f A A1 A2 A3
4 ID_2 f B B1 B2 B3
如何:
> dat <- data.frame(id=c("id1","id2"),gender=c("m","f"),a.1=1:2,a.2=1:2,a.3=1:2,b.1=3:4,b.2=3:4,b.3=3:4)
> dat1 <- dat[,-(3:5)]
> dat2 <- dat[,-(6:8)]
> names(dat1)[3:5] <- c("v1","v2","v3")
> names(dat2)[3:5] <- c("v1","v2","v3")
>
> dat1$test <- "b"
> dat2$test <- "a"
> result <- rbind(dat1,dat2)
> dat
id gender a.1 a.2 a.3 b.1 b.2 b.3
1 id1 m 1 1 1 3 3 3
2 id2 f 2 2 2 4 4 4
> result
id gender v1 v2 v3 test
1 id1 m 3 3 3 b
2 id2 f 4 4 4 b
3 id1 m 1 1 1 a
4 id2 f 2 2 2 a
我喜欢Brian的回答更好,但这里有一个方法与基本包做。虽然在我看来很丑。
您的数据框:
DF
id sex v1 v2 v3 v4 v5 v6
1 ID_1 male A1 A2 A3 B1 B2 B3
2 ID_2 female A1 A2 A3 B1 B2 B3
代码
DFa<-subset(DF, select=c(1:5))
DFb<-subset(DF, select=c(1:2, 6:8))
colnames(DFb)<-colnames(DFa)
DF<-as.data.frame(rbind(DFa,DFb))
rownames(DF)<-1:nrow(DF)
DF[order(DF$id),]
约翰我不同意。我看到输出与OP的预期结果相同。只有4行不是6,所以我不明白你的批评。 –
我的答复和其他答案之间的唯一区别是我不给A和B单独列,因为它是答案中固有的(这可能是一个问题,但如果A1,A2,B1 ...实际上是数字)我对这些行进行了重新排序以匹配所需的结果。这是一个简单的情况,分裂列和restacking。 –
当我第一次复制和粘贴你的代码时,它出于某种原因做了6行。现在它不。抱歉。 – John
告诉'melt'的前两列分别为id的变量,即'id.vars = ...' – Andrie
第一部分工作,保留第一列是没有问题的,但是我不知道如何告诉R它应该重新排列所有Test1(A1,B1)/ Test2(A2,B2)等等。因此,我最终得到了三个而不是六个列(例如两个)... – Elisa
@Elisa,这看起来像是你几个小时前创建的问题的重复。如果是,请关闭另一个。 – Ramnath