2016-02-07 3 views
1

Im пытается использовать пакет 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

Мы можем использовать melt из data.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 

Или с помощью reshape из base R и указать 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 

Или другой вариант был бы merged.stack от library(splitstackshape). Если нам нужно преобразовать в «длинный» формат на основе суффикса в именах столбцов, получите суффикс имен столбцов с sub и используйте элементы unique в var.stubs вместе с указанием 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

Большое спасибо akrun! но есть ли способ сделать это, чтобы я мог использовать «.». как разделитель вместо того, чтобы печатать имена столбцов? –

+0

@richard_jokes Поскольку оба префикса и суффикса различаются друг от друга, одним из способов было бы указать столбцы в 'variableing' как' list' в вашей перестановке. то есть 'reshape (mydata, direction = 'long', variableing = list (2: 4, 5: 7))' – akrun

+0

@richard_jokes Я добавил еще несколько вариантов. Надеюсь, поможет. – akrun