2013-08-19 106 views
2

重塑列的块可以说我有与这些列的data.table- [R data.table一次

nodeID 
hour1aaa 
hour1bbb 
hour1ccc 
hour2aaa 
hour2bbb 
hour2ccc 
... 
hour24aaa 
hour24bbb 
hour24ccc 

,总共72列。让我们把它rawtable

我想重塑它,所以我有

nodeID 
hour 
aaa 
bbb 
ccc 

总共只有这5列 在小时列将包含取其小时从原来的72,它应该是的。 我们称之为newshape

我现在要做的方式是使用rbindlist和24个项目,其中每个项目都是更大的data.table的正确子集。像这样的(除非我要离开了大部分的时间在我的例子)

newshape<-rbindlist(list(
rawtable[,list(nodeID, Hour=1, aaa=hour1aaa, bbb=hour1bbb, ccc=hour1ccc)], 
rawtable[,list(nodeID, Hour=2, aaa=hour2aaa, bbb=hour2bbb, ccc=hour2ccc)], 
rawtable[,list(nodeID, Hour=24, aaa=hour24aaa, bbb=hour24bbb, ccc=hour24ccc)])) 

下面是一些样本数据与

rawtable<-data.table(nodeID=c(1,2),hour1aaa=c(12.4,32),hour1bbb=c(61.1,65.33),hour1ccc=c(-4.2,54),hour2aaa=c(12.2,1.2),hour2bbb=c(12.2,5.7),hour2ccc=c(5.6,101.9),hour24aaa=c(45.2,8.5),hour24bbb=c(23,7.9),hour24ccc=c(98,32.3)) 

用我rbindlist办法发挥出预期的结果,但是,作为对于我用R做的大多数事情,可能有更好的方法。更好的意思是更高效的内存,更快,和/或使用更少的代码行。有没有人有更好的方法来实现这一目标?

回答

3

这是一个经典reshape问题,如果你在它期望的标准惯​​例让你的名字,但我不知道这真的驾data.table结构的效率:

reshape(
    setNames(rawtable, gsub("(\\D+)(\\d+)(\\D+)", "\\3.\\2", names(rawtable))), 
    idvar="nodeID", direction="long", varying=-1 
) 

结果:

nodeID hour aaa bbb ccc 
1:  1 1 12.4 61.10 -4.2 
2:  2 1 32.0 65.33 54.0 
3:  1 2 12.2 12.20 5.6 
4:  2 2 1.2 5.70 101.9 
5:  1 24 45.2 23.00 98.0 
6:  2 24 8.5 7.90 32.3 

@Arun的在这里回答:https://stackoverflow.com/a/15510828/496803也可能是有用的,如果你能使其适应当前的数据。

+0

+1我不认为会有很多与基础R重塑问题。它总是让我觉得'reshape'并不费力去找出'vary = list(...)'部分,尤其是当你必须在这些情况下指定'v.names'时。 – A5C1D2H2I1M1N2O1R2T1

+0

@AnandaMahto - 我想是一个小的代价。你可以在''vary''和''''''''''''''''''''''''''''''''''''''''''''''''''''' v.names'部分。虽然这有点不方便。 – thelatemail

+0

我在我的函数中为这样的目的定义了一个矢量化的'grep':'vGrep < - Vectorize(grep,“pattern”,SIMPLIFY = FALSE)'。 – A5C1D2H2I1M1N2O1R2T1

2

一个选择是从我的包“splitstackshape”中使用merged.stack。这个函数,stack的一组列,然后将输出合并在一起。由于该函数如何创建“时间”变量,因此可以指定想要从列名称中去除的任何内容。在这种情况下,我们要删除“小时”,“aaa”,“bbb”和“ccc”,并只剩下数字。

library(splitstackshape) 
## Make sure you're using at least 1.2.0 
packageVersion("splitstackshape") 
# [1] ‘1.2.0’ 
merged.stack(rawtable, id.vars="nodeID", 
      var.stubs=c("aaa", "bbb", "ccc"), 
      sep="hour|aaa|bbb|ccc") 
# nodeID .time_1 aaa bbb ccc 
# 1:  1  1 12.4 61.10 -4.2 
# 2:  1  2 12.2 12.20 5.6 
# 3:  1  24 45.2 23.00 98.0 
# 4:  2  1 32.0 65.33 54.0 
# 5:  2  2 1.2 5.70 101.9 
# 6:  2  24 8.5 7.90 32.3