分裂时重新变长

时间:2014-05-22 07:29:48

标签: r reshape2 tidyr melt

我正在寻找重塑:

  ID p2012 p2010 p2008 p2006 c2012 c2010 c2008 c2006
1  1   160   162   163   165  37.3  37.3  37.1  37.1
2  2   163   164   164   163   2.6   2.6   2.6   2.6

成:

    ID  year    p   c
1   1   2006    165 37.1
2   1   2008    164 37.1
3   1   2010    162 37.3
4   1   2012    160 37.3
5   2   2006    163 2.6
6   2   2008    163 2.6
7   2   2010    164 2.6
8   2   2012    163 2.6

我是R的新手,一直在尝试meltdcast功能,但在这个阶段我只有很多曲折。非常感谢帮助!

我的df的dput

structure(list(ID = 1:2, p2012 = c(160L, 163L), p2010 = c(162L, 164L), p2008 = 163:164, p2006 = c(165L, 163L), c2012 = c(37.3, 2.6), c2010 = c(37.3, 2.6), c2008 = c(37.1, 2.6), c2006 = c(37.1, 2.6)), .Names = c("ID", "p2012", "p2010", "p2008", "p2006", "c2012", "c2010", "c2008", "c2006"), class = "data.frame", row.names = c(NA, -2L))

3 个答案:

答案 0 :(得分:4)

阴影答案的替代方法是使用reshape函数:

reshape(d, direction='long', varying=list(2:5, 6:9), v.names=c("p", "c"), idvar="ID", times=c(2012, 2010, 2008, 2006))

这假设您事先知道pc的列索引(或添加其他代码来计算出来)。此外,通过使用类似于阴影的gsub函数的东西,可以找到上面的时间向量。

使用哪种方式可能是一种品味问题。

答案 1 :(得分:2)

您可能必须首先melt数据,然后将变量和年份拆分,然后将dcast拆分为最终的data.frame

require(reshape2)
# melt data.frame
dfmelt <- melt(df, id.vars="ID", variable.name="var.year")
# split "var.year" into new variables "var" and "year" 
dfmelt[, "var"] <- gsub("[0-9]", "", as.character(dfmelt[, "var.year"]))
dfmelt[, "year"] <- as.numeric(gsub("[a-z, A-Z]", "", as.character(dfmelt[, "var.year"])))
# cast to data with column for each var-name
dcast(dfmelt, ID+year~var, value.var="value")

答案 2 :(得分:2)

可以使用tidyr中的以下解决方案。如果&#34; p&#34;你实际上不需要使用正则表达式。或&#34; c&#34;始终是列名的第一个字母:

library(tidyr)
library(dplyr) # only loaded for the %>% operator

dat %>%
  gather(key,value,p2012:c2006) %>%
  separate(key,c("category","year"),1) %>%
  spread(category,value)
  ID year    c   p
1  1 2006 37.1 165
2  1 2008 37.1 163
3  1 2010 37.3 162
4  1 2012 37.3 160
5  2 2006  2.6 163
6  2 2008  2.6 164
7  2 2010  2.6 164
8  2 2012  2.6 163