熔化投射数据帧会导致输出错误

时间:2010-03-03 09:45:15

标签: r reshape

我在castmelt / reshape中遇到了一个奇怪的行为。如果我投了data.frame,然后尝试melt,那么melt就出错了。从演员data.frame手动取消设置“df.melt”类可以让它正确融化。

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

显示行为的小代码示例:

> 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

2 个答案:

答案 0 :(得分:2)

我知道这是一个老问题,不太可能引起很多兴趣。我也无法弄清楚为什么你正在做你在你的例子中展示的东西。然而,要总结答案,要么:

  1. 再次“融化”之前,将df.cast包裹在as.data.frame
  2. Ditch“重塑”并更新为“reshape2”。当您发布此问题时,这不适用,因为您的问题早于“reshape2”的版本1大约半年。
  3. 这是一个更长的走路:

    首先,我们将加载“reshape”和“reshape2”,执行“cast”,并重命名“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”,那么您在尝试做的事情上不会遇到任何问题< / LI>
    • 哇。 str(df.cast.R1)的输出是我见过的最奇怪的data.frame!实际上看起来有两个单变量data.frame

    借助这些新知识,并且我们不希望更改您投放class的{​​{1}}的前提条件,让我们继续:

    data.frame

    如果您仍然使用“reshape”中的# 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 ,请考虑升级到“reshape2”,或者在cast周围写一个便利包装函数...也许melt?< / p>

    melt2

    melt2 <- function(data, ...) { ifelse(isTRUE("cast_df" %in% class(data)), data <- as.data.frame(data), data <- data) melt(data, ...) } 上试用:

    df.cast.R1

答案 1 :(得分:1)

您需要在> 之前融合数据框。首先不进行熔化的铸造会产生各种意外行为,因为重塑必须猜测数据的结构。