我有一个大型数据框,直接从SQL数据库导入,具有以下类型的结构(对于可重现的示例):
我想要考虑前3列,'id','day'和'type'。这3列始终相互依赖并相应地分解。 对于因子列,我想将列'valueTitle'转换为行作为新的列标题,并将列'value'转换为正确的'valueTitle'下的行。看起来应该是这样的:
可重复的例子:
id <- c(5,5,5,6,6,6,7,7,7)
day <- c("01.01.2000", "01.01.2000", "01.01.2000", "01.01.2001", "01.01.2001", "01.01.2001", "01.01.2002", "01.01.2002", "01.01.2002")
type <- c("green", "green", "green","orange","orange","orange", "blue", "blue", "blue")
valueTitle <- c("title1","title2","title3","title1","title2","title3","title1","title2","title3")
value <- c(0.2, 0.6, 0.9, 0.6, 0.9, 0.9, 2, 1, 7)
df <- data.frame(id, day, type, valueTitle, value)
df$id<-as.factor(df$id)
df
id day type valueTitle value
1 5 01.01.2000 green title1 0.2
2 5 01.01.2000 green title2 0.6
3 5 01.01.2000 green title3 0.9
4 6 01.01.2001 orange title1 0.6
5 6 01.01.2001 orange title2 0.9
6 6 01.01.2001 orange title3 0.9
7 7 01.01.2002 blue title1 2.0
8 7 01.01.2002 blue title2 1.0
9 7 01.01.2002 blue title3 7.0
我一直在寻找一种只使用矢量化操作的解决方案,但是对此很长时间以来并没有找到好方法。我只提出了以下解决方案,但是基于一个循环,这看起来很错误有很多原因:
m<-matrix(ncol=3,nrow=3); m<-as.data.frame(m);m # pretend I know the real size, in reality this is not fixed
for ( i in min(levels(df$id)):max(levels(df$id))){
m[(df$id==i), ]<-(df[ ,('value')])
}
m<-t(m)
df2<-data.frame(m)
colnames(df2)<-(levels(df$valueTitle))
df2 <- cbind(id=levels(df$id), df2[,1:ncol(df2)])
df2
id day type title1 title2 title3
V1 5 01.01.2000 blue 0.2 0.6 0.9
V2 6 01.01.2001 green 0.6 0.9 0.9
V3 7 01.01.2002 orange 2.0 1.0 7.0
这是错误的,因为&#39;键入&#39;混淆了,无论哪种方式,这种方法都会导致许多潜在的错误。我的真实数据集很大,而且数量很多&#39; valueTitle&#39;可以根据不同的身份而有所不同。
你能否建议任何能更有效地执行因子并对这些数据进行转置操作的方法?
(如果有一种方法可以直接在SQL中执行此操作,那也很不错!)
答案 0 :(得分:2)
我们可以使用dcast
library(reshape2)
dcast(df, id+day+type~valueTitle, value.var='value')
或来自spread
的{{1}}来重塑&#39; long&#39;格式为&#39; wide&#39;。
tidyr
答案 1 :(得分:1)
使用PIVOT
:
CREATE TABLE #tab (
id INTEGER NOT NULL
,[day] DATE NOT NULL
,type VARCHAR(100) NOT NULL
,valueTitle VARCHAR(60) NOT NULL
,value NUMERIC(10,2) NOT NULL);
INSERT INTO #tab (id,[day],type,valueTitle,value)
VALUES (5,'2000-01-01','green','title1',0.2), (5,'2000-01-01','green','title2',0.6),
(5,'2000-01-01','green','title3',0.9), (6,'2001-01-01','orange','title1',0.6),
(6,'2001-01-01','orange','title2',0.9),(6,'2001-01-01','orange','title3',0.9),
(7,'2002-01-01','blue','title1',2.0), (7,'2002-01-01','blue','title2',1.0),
(7,'2002-01-01','blue','title3',7.0);
SELECT id, [day], type,title1, title2, title3
FROM #tab
PIVOT (MAX(value)
FOR valueTitle IN (title1, title2, title3)) p;
的 LiveDemo
强>