web-dev-qa-db-fra.com

Quels sont les niveaux dans R?

Je comprends que c’est une question très fondamentale, mais je ne comprends pas ce que signifient les niveaux dans R.

Pour référence, j'ai fait un script simple pour lire la table CSV, filtrer sur l'un des champs, le transmettre à une nouvelle variable et vider la mémoire allouée à la première variable. Si j'appelle unique () sur le champ sur lequel j'ai filtré, je constate que les résultats ont bien été filtrés, mais il existe une ligne supplémentaire indiquant les "Niveaux" correspondant aux données contenues dans le jeu de données d'origine.

Exemple:

df = read.csv(path, sep=",", header=TRUE)
df_intrate = df[df$AssetClass == "ASSET CLASS A", ]

rm(df)
gc()

unique(df_intrate$AssetClass)

Résultats:

[1] ASSET CLASS A
Levels: ASSET CLASS E ASSET CLASS D ASSET CLASS C ASSET CLASS B ASSET CLASS A

Est-ce que les informations structurelles de df sont en quelque sorte conservées dans df_intrate malgré que R studio ait montré que df_intrate est bien le nombre de lignes attendu pour ASSET CLASS A?

6
ApplePie

Les informations structurelles de df sont-elles en quelque sorte conservées dans df_intrate malgré le fait que R studio indique que df_intrate correspond bien au nombre de lignes attendu pour ASSET CLASS A?

Oui. Voici comment les variables catégorielles, appelées facteurs, sont stockées dans R - à la fois le levels, un vecteur de toutes les valeurs possibles, et les valeurs réelles prises sont stockés:

x = factor(c('a', 'b', 'c', 'a', 'b', 'b'))
x
# [1] a b c a b b
# Levels: a b c

y = x[1]
# [1] a
# Levels: a b c

Vous pouvez vous débarrasser des niveaux inutilisés avec droplevels() ou en réappliquant la fonction factor en créant un nouveau facteur à partir de ce qui est présent:

droplevels(y)
# [1] a
# Levels: a

factor(y)
# [1] a
# Levels: a

Vous pouvez également utiliser droplevels sur un bloc de données pour supprimer tous les niveaux inutilisés de toutes les colonnes de facteurs:

dat = data.frame(x = x)
str(dat)
# 'data.frame': 6 obs. of  1 variable:
#  $ x: Factor w/ 3 levels "a","b","c": 1 2 3 1 2 2

str(dat[1, ])
# Factor w/ 3 levels "a","b","c": 1

str(droplevels(dat[1, ]))
# Factor w/ 1 level "a": 1

Bien que n'étant pas lié à votre problème actuel, nous devrions également mentionner que factor a un argument optionnel levels qui peut être utilisé pour spécifier les niveaux d'un facteur et l'ordre dans lequel ils doivent être placés. Cela peut être utile si vous souhaitez un ordre spécifique (peut-être pour le traçage ou la modélisation), ou s'il y a plus de niveaux possibles que ceux réellement présents et que vous souhaitez les inclure. Si vous ne spécifiez pas levels, la valeur par défaut sera l'ordre alphabétique. 

x = c("agree", "disagree", "agree", "neutral", "strongly agree")
factor(x)
# [1] agree         disagree      agree         neutral       strongly agree
# Levels: agree disagree neutral strongly agree
## not a good order

factor(x, levels = c("disagree", "neutral", "agree", "strongly agree"))
# [1] agree          disagree       agree          neutral        strongly agree
# Levels: disagree neutral agree strongly agree
## better order

factor(x, levels = c("strongly disagree", "disagree", "neutral", "agree", "strongly agree"))
# [1] agree          disagree       agree          neutral        strongly agree
# Levels: strongly disagree disagree neutral agree strongly agree
## good order, more levels than are actually present

Vous pouvez utiliser ?reorder et ?relevel (ou simplement factor) pour modifier l'ordre des niveaux d'un facteur déjà créé.

4
Gregor

Vous voyez Levels dans la structure de données dans R appelée factor. Les facteurs sont de type entier:

typeof(as.factor(letters))
#[1] "integer"

Cependant, ils ont des étiquettes, qui mappent chaque entier à une spécification de caractère (une étiquette). Vous verrez que les facteurs sont généralement utiles dans les modèles où l'algorithme nécessite des nombres (parfois sous la forme de variables nominales), mais en conservant les étiquettes qui ont plus de sens pour les humains lors de l'interprétation du modèle.

Les niveaux sont un attribut du vecteur:

attributes(as.factor(letters))
#$levels
# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q"
#[18] "r" "s" "t" "u" "v" "w" "x" "y" "z"

#$class
#[1] "factor"

Ce qui signifie qu'une fois que vous sous-définissez votre colonne sur seulement ASSET CLASS A, les attributs de la colonne sont également transférés. Cela n'a rien à voir avec la longueur de votre vecteur bien que ce soit toujours [1].

2
LyzandeR

R a une classe character et une classe factor. character est votre structure de données de chaîne de base. factor est quelque chose d'important pour les statistiques: par exemple, vous pouvez avoir un ensemble de données dans lequel les personnes sont divisées par la connectivité de leurs lobes d'oreilles (une distinction importante mais souvent négligée). Dans un tel cas, pour chaque personne, ils auront une valeur connected ou free. Si vous deviez modéliser, par exemple, l'intelligence, en fonction du statut de connexion du lobe de l'oreille, vous voudriez que ce modèle comprenne qu'il existe deux classes de personnes: connected ou free, de sorte représenter cela comme un vecteur factor, et ce vecteur aurait deux levels: connected et free. Donc c'est sémantiquement pourquoi les niveaux sont une chose dans R.

Syntaxiquement, les variables factor et character répondent à as.integer différemment. Les variables factor sont converties en un nombre correspondant à leur niveau, alors qu'une variable character convertit davantage comme une variable traditionnelle atoi. En général, vous pouvez rencontrer beaucoup de problèmes si vous utilisez une variable factor en pensant que c'est un character.

Lorsque je lis un fichier csv, dans la plupart des cas, je trouve que je préfère avoir les valeurs character plutôt que factors, de sorte que je règle généralement read.csv(..., stringsAsFactor=FALSE). (YMMV si c'est votre préférence générale.)

1
flies