2013-08-19 145 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