Pergunta

Eu encontrei um comportamento estranho em cast/melt de reshape pacote.Se eu lançar um data.frame, e então tente melt isso, o melt sai errado.Desativando manualmente a classe "df.melt" do elenco data.frame permite que seja derretido corretamente.

Alguém sabe se esse é o comportamento pretendido e, em caso afirmativo, qual é o caso de uso quando você deseja?

Um pequeno exemplo de código que mostra o comportamento:

> 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
Foi útil?

Solução

Eu sei que esta é uma pergunta ANTIGA e provavelmente não gerará muito interesse.Eu também não consigo entender por que você está fazendo o que demonstra em seu exemplo.No entanto, para resumir a resposta:

  1. Embrulhe seu df.cast em as.data.frame antes de "derreter" novamente.
  2. Abandone "reshape" e atualize para "reshape2".Isso não era aplicável quando você postou esta pergunta, já que ela é anterior à versão 1 de "reshape2" em cerca de meio ano.

Aqui está um passo a passo mais longo:

Primeiro, carregaremos "reshape" e "reshape2", realizaremos sua "casting" e renomearemos sua variável "n".Obviamente, os objetos anexados com "R2" são aqueles de "reshape2" e "R1", de "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"

Em segundo lugar, vamos dar uma rápida olhada no que temos agora:

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

Algumas observações são óbvias:

  • Olhando para a saída de class, você pode adivinhar que você não terá problemas em fazer o que está tentando fazer se estiver usando "reshape2"
  • Uau.Essa saída de str(df.cast.R1) é a aparência mais estranha data.frame Que eu já vi!Na verdade, parece que existem duas variáveis ​​únicas data.frameestá aí.

Com estes novos conhecimentos, e com a condição de que não queremos alterar o class do seu elenco data.frame, vamos prosseguir:

# 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

Se você ainda está trabalhando com cast de "reshape", considere atualizar para "reshape2" ou escreva uma função wrapper conveniente em torno melt...talvez melt2?

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

Experimente 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

Outras dicas

Você precisa derreter o quadro de dados antes da você lançou. O lançamento sem derreter primeiro produzirá todos os tipos de comportamento inesperado, porque o RESHAPE precisa adivinhar a estrutura de seus dados.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top