如何将下面的data.frame转换为给定的矩阵? data.frame的前两列包含行变量,其他列的所有组合(包含值的除外)确定列。理想情况下,我正在寻找一个不需要进一步包的解决方案(所以没有 reshape2
解决方案)。此外,没有ftable
解决方案。
(df <- data.frame(c1=rep(c(1, 2), each=8), c2=rep(c(1, 2, 1, 2), each=4),
gr=rep(c(1, 2), 8), subgr=rep(c(1,2), 4, each=2), val=1:16) )
c1 c2 gr1.subgr1 gr1.subgr2 gr2.subgr1 gr2.subgr2
1 1 1 3 2 4
1 2 5 7 6 8
2 1 9 11 10 12
2 2 13 15 14 16
答案 0 :(得分:4)
使用交互变量构建组:
newdf <- reshape(df, idvar=1:2, direction="wide",
timevar=interaction(df$gr,df$subgr) ,
v.names="val",
drop=c("gr","subgr") )
names(newdf)[3:6] <- c("gr1.subgr1", "gr1.subgr2", "gr2.subgr1", "gr2.subgr2")
newdf
c1 c2 gr1.subgr1 gr1.subgr2 gr2.subgr1 gr2.subgr2
1 1 1 1 2 3 4
5 1 2 5 6 7 8
9 2 1 9 10 11 12
13 2 2 13 14 15 16
答案 1 :(得分:2)
好吧 - 看起来它主要是你想要的。从阅读帮助文件,这似乎应该做你想要的:
reshape(df, idvar = c("c1", "c2"), timevar = c("gr", "subgr")
, direction = "wide")
c1 c2 val.c(1, 2, 1, 2) val.c(1, 1, 2, 2)
1 1 1 NA NA
5 1 2 NA NA
9 2 1 NA NA
13 2 2 NA NA
我无法完全解释为什么它会出现NA值。但是,也许帮助页面中的这一点解释了:
timevar
the variable in long format that differentiates multiple records from the same
group or individual. If more than one record matches, the first will be taken.
我最初认为,如果你给它的列名有歧义,R会使用它的部分匹配功能,但也许不是吗?接下来,我尝试将gr
和subgr
合并为一个列:
df$newcol <- with(df, paste("gr.", gr, "subgr.", subgr, sep = ""))
让我们再试一次:
reshape(df, idvar = c("c1", "c2"), timevar = "newcol"
, direction = "wide", drop= c("gr","subgr"))
c1 c2 val.gr.1subgr.1 val.gr.2subgr.1 val.gr.1subgr.2 val.gr.2subgr.2
1 1 1 1 2 3 4
5 1 2 5 6 7 8
9 2 1 9 10 11 12
13 2 2 13 14 15 16
的Presto!我无法解释或弄清楚如何使它不会将val.
附加到列名称上,但我会让你自己解决这个问题。我确定它在某个帮助页面上。它还使组的顺序与您请求的顺序不同,但数据似乎是正确的。
FWIW,这是一个reshape2
> dcast(c1 + c2 ~ gr + subgr, data = df, value.var = "val")
c1 c2 1_1 1_2 2_1 2_2
1 1 1 1 3 2 4
2 1 2 5 7 6 8
3 2 1 9 11 10 12
4 2 2 13 15 14 16
虽然您仍需要清理列名。