使用 reshape2 重塑带分隔符的数据
Reshape data with separator using 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
关于如何解决这个问题有什么想法吗?
我们可以使用 data.table
中的 melt
,它可以包含多个 measure
列
library(data.table)
dM <- melt(setDT(mydata), measure=patterns('Price', 'Rating'),
variable.name='ID', value.name=c('Price', 'Rating'))
默认情况下,'variable'(即'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 R
中的 reshape
并将 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)
。如果我们需要根据列名中的后缀部分转成'long'格式,则用sub
获取列名的后缀,使用var.stubs
中的unique
元素以及将 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
我正在尝试使用 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
关于如何解决这个问题有什么想法吗?
我们可以使用 data.table
中的 melt
,它可以包含多个 measure
列
library(data.table)
dM <- melt(setDT(mydata), measure=patterns('Price', 'Rating'),
variable.name='ID', value.name=c('Price', 'Rating'))
默认情况下,'variable'(即'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 R
中的 reshape
并将 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)
。如果我们需要根据列名中的后缀部分转成'long'格式,则用sub
获取列名的后缀,使用var.stubs
中的unique
元素以及将 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