2010-03-03 47 views
1

我在reshape包中遇到了cast/melt中的奇怪行爲。如果我投了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

我很困惑。你爲什麼要熔化已經是長格式的df?而你使用'cast'也沒有多大意義。通常你在使用'melt'之後使用它*。 – Harlan 2010-03-03 22:19:07

+1

請詳細解釋一下你想要做什麼以及你的預期結果。 – 2010-03-04 03:06:27

回答

2

我知道這是一個老問題,不太可能產生很多興趣。我也無法弄清楚爲什麼你正在做你在你的例子中演示的東西。儘管如此,總結答案,或者:

  1. 「融化」了之前包裹在as.data.framedf.cast
  2. 溝「重塑」並更新爲「重塑2」。當你發佈這個問題時,這是不適用的,因爲你的問題比「reshape2」的版本1早約半年。

這裏有一個更長的walktrhough:

首先,我們將載入 「重塑」 和 「reshape2」,執行你的 「鑄造」,並重新命名您的 「N」 變量。顯然,附加了「R2」的對象是來自「重塑」的「重塑2」和「R1」的那些。

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

有了這個新的知識,並與前提,我們不想改變你的鑄造data.frameclass,讓我們繼續:

# 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工作從「重塑」,考慮升級到「重塑2」,或者圍繞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 
+0

+1結果良好的答案!我仍然需要切換到reshape2,雖然... – 2013-01-28 08:32:12

+0

@PaulHiemstra,你有沒有切換的原因? (問一個一般會堅持基礎R重塑他的所有重塑需求的人)。 – A5C1D2H2I1M1N2O1R2T1 2013-01-28 08:34:03

+0

我只是沒有覺得需要,我主要用'melt'來準備ggplot2或plyr的數據,而不是更多。 – 2013-01-28 08:37:26

1

你需要你施展它之前融化數據幀。因爲重塑必須猜測數據的結構,所以不先熔鑄就會產生各種意想不到的行爲。