我知道这是一个老问题,不太可能引起很多兴趣。我也不太明白你为什么要做你在你的例子中展示的东西。尽管如此,总结答案,要么:
- 在再次“融化”之前将你
df.cast
的包裹起来。as.data.frame
- 抛弃“reshape”并更新为“reshape2”。当您发布此问题时,这并不适用,因为您的问题比“reshape2”的第 1 版早了大约半年。
这是一个更长的演练:
首先,我们将加载“reshape”和“reshape2”,执行你的“casting”,并重命名你的“n”变量。显然,带有“R2”的对象是来自“reshape2”的对象,而“R1”是来自“reshape”的对象。
library(reshape)
library(reshape2)
df.cast.R2 <- dcast(df, type~., sum)
df.cast.R1 <- cast(df, type~., sum)
names(df.cast.R1)[2] <- "n"
names(df.cast.R2)[2] <- "n"
其次,让我们快速看看我们现在得到了什么:
class(df.cast.R1)
# [1] "cast_df" "data.frame"
class(df.cast.R2)
[1] "data.frame"
str(df.cast.R1)
# List of 2
# $ type: num [1:3] 1 2 3
# $ n : num [1:3] 143 148 41
# - attr(*, "row.names")= int [1:3] 1 2 3
# - attr(*, "idvars")= chr "type"
# - attr(*, "rdimnames")=List of 2
# ..$ :'data.frame': 3 obs. of 1 variable:
# .. ..$ type: num [1:3] 1 2 3
# ..$ :'data.frame': 1 obs. of 1 variable:
# .. ..$ value: Factor w/ 1 level "(all)": 1
str(df.cast.R2)
# 'data.frame': 3 obs. of 2 variables:
# $ type: num 1 2 3
# $ n : num 143 148 41
一些观察是显而易见的:
- 通过查看 的输出
class
,您可以猜到如果您使用“reshape2”,您将不会遇到任何问题
- 哇。的输出是我见过
str(df.cast.R1)
的最奇怪的外观!data.frame
实际上看起来那里有两个单变量data.frame
。
有了这些新知识,并且在我们不想更改class
您的 cast的前提下data.frame
,让我们继续:
# You don't want this
melt(df.cast.R1, id="type", measure="n")
# type value value
# X.all. 1 143 (all)
# X.all..1 2 148 (all)
# X.all..2 3 41 (all)
# You *do* want this
melt(as.data.frame(df.cast.R1), id="type", measure="n")
# type variable value
# 1 1 n 143
# 2 2 n 148
# 3 3 n 41
# And the class has not bee altered
class(df.cast.R1)
# [1] "cast_df" "data.frame"
# As predicted, this works too.
melt(df.cast.R2, id="type", measure="n")
# type variable value
# 1 1 n 143
# 2 2 n 148
# 3 3 n 41
如果您仍在使用cast
“reshape”,请考虑升级到“reshape2”,或者编写一个方便的包装函数melt
......也许melt2
?
melt2 <- function(data, ...) {
ifelse(isTRUE("cast_df" %in% class(data)),
data <- as.data.frame(data),
data <- data)
melt(data, ...)
}
试试看df.cast.R1
:
melt2(df.cast.R, id="type", measure="n")
# ype variable value
# 1 1 n 143
# 2 2 n 148
# 3 3 n 41