2016-02-07 46 views
1

我試圖使用reshape2包重新整理我的數據,但出現錯誤。我的數據如下:使用reshape2重塑使用分隔符的數據

mydata<-read.csv("Data.csv") 
head(mydata)  
     Date A.Price B.Price C.Price A.Rating B.Rating C.Rating 
31/01/2012 1.273 3.11 1.215  5  4  3 
29/02/2012 1.393 3.19 1.205  10  8  7 
30/03/2012 1.367 3.15 1.076  10.5  9.5  7.5 

我的目標是把它重塑了這個:

Date  ID Price Rating 
31/01/2012 A 1.273 5 
31/01/2012 B 3.11 4 
31/01/2012 C 1.215 3 
29/02/2012 A 1.393 10 
29/02/2012 B 3.19 8 
.... 

到目前爲止,我的代碼是:

mydata$ID <- sequence(nrow(mydata)) 
out<-melt(reshape(mydata, direction = "long", 
    timevar = "Group", varying = names(mydata), sep = "."), 
     id.vars = c("ID", "Price","Rating")) 

但即時得到錯誤:

Error in reshapeLong(data, idvar = idvar, timevar = timevar, varying = varying, : 'varying' arguments must be the same length

關於如何解決這個問題的任何想法?

回答

2

我們可以使用meltdata.table可以採取多個measure

library(data.table) 
dM <- melt(setDT(mydata), measure=patterns('Price', 'Rating'), 
    variable.name='ID', value.name=c('Price', 'Rating')) 

默認情況下, '可變'(即 'ID')列輸出作爲數字索引。我們可以使用sub從列名中獲取前綴並更新'ID'列。

dM[, ID:= sub('\\..*', '', names(mydata)[-1])[ID]] 
dM 
#   Date ID Price Rating 
#1: 31/01/2012 A 1.273 5.0 
#2: 29/02/2012 A 1.393 10.0 
#3: 30/03/2012 A 1.367 10.5 
#4: 31/01/2012 B 3.110 4.0 
#5: 29/02/2012 B 3.190 8.0 
#6: 30/03/2012 B 3.150 9.5 
#7: 31/01/2012 C 1.215 3.0 
#8: 29/02/2012 C 1.205 7.0 
#9: 30/03/2012 C 1.076 7.5 

,或利用base Rreshape並指定varying爲列索引列表。我們可以得到指數與grep

nm1 <- unique(sub('.*\\.', '', names(mydata)[-1])) 
res <- reshape(mydata, direction='long', varying= lapply(nm1, 
      grep, names(mydata))) 
row.names(res) <- NULL 
head(res) 
#  Date time A.Price A.Rating id 
#1 31/01/2012 1 1.273  5.0 1 
#2 29/02/2012 1 1.393  10.0 2 
#3 30/03/2012 1 1.367  10.5 3 
#4 31/01/2012 2 3.110  4.0 1 
#5 29/02/2012 2 3.190  8.0 2 
#6 30/03/2012 2 3.150  9.5 3 

或者另一個選擇是從library(splitstackshape)merged.stack。如果我們需要根據列名稱中的後綴部分轉換爲'long'格式,請獲取帶有sub的列名後綴,並使用var.stubs中的unique元素以及將sep指定爲'var.stubs in merged.stack `。

library(splitstackshape) 
nm1 <- unique(sub('.*\\.', '', names(mydata)[-1]))#from above 
merged.stack(mydata, var.stubs =nm1, atStart=FALSE, 
    sep='var.stubs')[, .time_1:= sub('[.]+', '', .time_1)][] 
#   Date .time_1 Price Rating 
#1: 29/02/2012  A 1.393 10.0 
#2: 29/02/2012  B 3.190 8.0 
#3: 29/02/2012  C 1.205 7.0 
#4: 30/03/2012  A 1.367 10.5 
#5: 30/03/2012  B 3.150 9.5 
#6: 30/03/2012  C 1.076 7.5 
#7: 31/01/2012  A 1.273 5.0 
#8: 31/01/2012  B 3.110 4.0 
#9: 31/01/2012  C 1.215 3.0 
+0

非常感謝!但有沒有辦法做到這一點,以便我可以使用「。」作爲分隔符而不是輸入列的名稱? –

+0

@richard_jokes因爲前綴和後綴都是變化的,所以一種方法是在變形中將'vary'中的列指定爲'list'。即'重塑(mydata,direction ='long',vary = list(2:4,5:7))' – akrun

+0

@richard_jokes我增加了一些選項。希望能幫助到你。 – akrun