1

我在包裹中cast/meltreshape包裹中遇到了奇怪的行为。如果我投 a data.frame,然后尝试melt它,结果melt是错误的。从演员表中手动取消设置“df.melt”类data.frame可以使其正确熔化。

有谁知道这是否是预期的行为,如果是,你想要它的用例是什么?

一个显示行为的小代码示例:

> df <- data.frame(type=c(1, 1, 2, 2, 3, 3), variable="n", value=c(71, 72, 68, 80, 21, 20))

> df
  type variable value
1    1        n    71
2    1        n    72
3    2        n    68
4    2        n    80
5    3        n    21
6    3        n    20

> df.cast <- cast(df, type~., sum)
> names(df.cast)[2] <- "n"

> df.cast
  type   n
1    1 143
2    2 148
3    3  41

> class(df.cast)
[1] "cast_df"    "data.frame"

> melt(df.cast, id="type", measure="n")
         type value value
X.all.      1   143 (all)
X.all..1    2   148 (all)
X.all..2    3    41 (all)

> class(df.cast) <- "data.frame"
> class(df.cast)
[1] "data.frame"

> melt(df.cast, id="type", measure="n")
  type variable value
1    1        n   143
2    2        n   148
3    3        n    41
4

2 回答 2

2

我知道这是一个老问题,不太可能引起很多兴趣。我也不太明白你为什么要做你在你的例子中展示的东西。尽管如此,总结答案,要么:

  1. 在再次“融化”之前将你df.cast的包裹起来。as.data.frame
  2. 抛弃“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
于 2013-01-28T08:20:18.817 回答
1

您需要在投射之前融化数据框。铸造而不先熔化会产生各种意想不到的行为,因为 reshape 必须猜测数据的结构。

于 2011-05-11T19:17:02.053 回答