web-dev-qa-db-fra.com

remodeler le message d'avertissement de fusion

J'utilise melt et rencontre le message d'avertissement suivant:
attributes are not identical across measure variables; they will be dropped

Après avoir regardé autour de nous, les gens ont mentionné que c'est parce que les variables sont de classes différentes; cependant, ce n'est pas le cas avec mon jeu de données.

Voici l'ensemble de données:

test <- structure(list(park = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L), .Label = c("miss", "piro", "sacn", "slbe"), class = "factor"), 
    a1.one = structure(c(3L, 1L, 3L, 3L, 3L, 3L, 1L, 3L, 3L, 
    3L), .Label = c("agriculture", "beaver", "development", "flooding", 
    "forest_pathogen", "harvest_00_20", "harvest_30_60", "harvest_70_90", 
    "none"), class = "factor"), a2.one = structure(c(6L, 6L, 
    6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L), .Label = c("development", 
    "forest_pathogen", "harvest_00_20", "harvest_30_60", "harvest_70_90", 
    "none"), class = "factor"), a3.one = structure(c(3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), .Label = c("forest_pathogen", 
    "harvest_00_20", "none"), class = "factor"), a1.two = structure(c(3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), .Label = c("agriculture", 
    "beaver", "development", "flooding", "forest_pathogen", "harvest_00_20", 
    "harvest_30_60", "harvest_70_90", "none"), class = "factor"), 
    a2.two = structure(c(6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
    6L), .Label = c("development", "forest_pathogen", "harvest_00_20", 
    "harvest_30_60", "harvest_70_90", "none"), class = "factor"), 
    a3.two = structure(c(3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L), .Label = c("forest_pathogen", "harvest_00_20", "none"
    ), class = "factor")), .Names = c("park", "a1.one", "a2.one", 
"a3.one", "a1.two", "a2.two", "a3.two"), row.names = c(NA, 10L
), class = "data.frame")

Et voici la structure:

str(test)
'data.frame':   10 obs. of  7 variables:
 $ park  : Factor w/ 4 levels "miss","piro",..: 1 1 1 1 1 1 1 1 1 1
 $ a1.one: Factor w/ 9 levels "agriculture",..: 3 1 3 3 3 3 1 3 3 3
 $ a2.one: Factor w/ 6 levels "development",..: 6 6 6 6 6 6 6 6 6 6
 $ a3.one: Factor w/ 3 levels "forest_pathogen",..: 3 3 3 3 3 3 3 3 3 3
 $ a1.two: Factor w/ 9 levels "agriculture",..: 3 3 3 3 3 3 3 3 3 3
 $ a2.two: Factor w/ 6 levels "development",..: 6 6 6 6 6 6 6 6 6 6
 $ a3.two: Factor w/ 3 levels "forest_pathogen",..: 3 3 3 3 3 3 3 3 3 3

Est-ce parce que le nombre de niveaux est différent pour chaque variable? Alors, puis-je simplement ignorer le message d'avertissement dans ce cas?

Pour générer le message d'avertissement:

library(reshape2)
test.m <- melt (test,id.vars=c('park'))
Warning message:
attributes are not identical across measure variables; they will be dropped

Merci.

50
cherrytree

Une explication:

Lorsque vous fondez, vous combinez plusieurs colonnes en une seule. Dans ce cas, vous combinez des colonnes de facteurs, chacune ayant un attribut levels. Ces niveaux ne sont pas les mêmes d'une colonne à l'autre car vos facteurs sont en réalité différents. melt contraint simplement chaque facteur en caractère et supprime leurs attributs lors de la création de la colonne value dans le résultat.

Dans ce cas, l'avertissement n'a pas d'importance, mais vous devez être très prudent lorsque vous combinez des colonnes qui ne sont pas du même "type", où "type" ne signifie pas seulement un type vectoriel, mais génériquement la nature des choses auxquelles il se réfère . Par exemple, je ne voudrais pas faire fondre une colonne contenant des vitesses en MPH avec une contenant des poids en LB.

Une façon de confirmer qu'il est correct de combiner vos colonnes de facteurs est de vous demander si une valeur possible dans une colonne serait une valeur raisonnable à avoir dans toutes les autres colonnes. Si tel est le cas, alors la bonne chose à faire serait probablement de s'assurer que chaque colonne de facteur a tous les niveaux possibles qu'elle pourrait accepter (dans le même ordre). Si vous faites cela, vous ne recevrez pas d'avertissement lorsque vous fondrez la table.

Une illustration:

library(reshape2)
DF <- data.frame(id=1:3, x=letters[1:3], y=rev(letters)[1:3])
str(DF)

Les niveaux pour x et y ne sont pas les mêmes:

'data.frame':  3 obs. of  3 variables:
$ id: int  1 2 3
$ x : Factor w/ 3 levels "a","b","c": 1 2 3
$ y : Factor w/ 3 levels "x","y","z": 3 2 1

Ici, nous melt et regardons la colonne x et y ont été fondus en (value):

melt(DF, id.vars="id")$value

Nous obtenons un vecteur de caractères et un avertissement:

[1] "a" "b" "c" "z" "y" "x"
Warning message:
attributes are not identical across measure variables; they will be dropped 

Si toutefois nous réinitialisons les facteurs pour qu'ils aient les mêmes niveaux et que ce soit ensuite fondre:

DF[2:3] <- lapply(DF[2:3], factor, levels=letters)
melt(DF, id.vars="id", factorsAsStrings=F)$value

Nous obtenons le bon facteur et aucun avertissement:

[1] a b c z y x
Levels: a b c d e f g h i j k l m n o p q r s t u v w x y z

Le comportement par défaut de melt est de baisser les niveaux des facteurs même lorsqu'ils sont identiques, c'est pourquoi nous utilisons factorsAsStrings=F au dessus de. Si vous n'aviez pas utilisé ce paramètre, vous auriez obtenu un vecteur de caractères, mais aucun avertissement. Je dirais que le comportement par défaut devrait être de conserver le résultat comme facteur, mais ce n'est pas le cas ici.

82
BrodieG

La réponse de BrodieG est excellente; cependant il y a des cas où il n'est pas pratique de refactoriser les colonnes (par exemple les données climatiques du GHCN avec 128 colonnes à largeur fixe que je voulais fondre dans un nombre beaucoup plus petit de colonnes).

Dans ce cas, la solution la plus simple consiste à traiter les données comme des caractères plutôt que comme des facteurs: par exemple, vous pouvez réimporter les données en utilisant read.fwf(filename,stringsAsFactors=FALSE) (la même idée fonctionnerait pour read.csv) . Pour un plus petit nombre de colonnes, vous pouvez convertir des facteurs en chaînes à l'aide de d$mystring<-as.character(d$myfactor).

1
John