Изменение формы данных с помощью разделителя с использованием 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"))
но я получаю ошибку:
Ошибка в reshapeLong(данные, idvar = idvar, timevar = timevar, варьирование = варьирование,: "переменные" аргументы должны быть одинаковой длины
Есть идеи, как это решить?
1 ответ
Мы можем использовать 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.stubsin
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