J'ai rencontré un comportement étrange lors de la suppression de colonnes de data.frame. Au départ, j'ai:

> a <- data.frame("a" = c(1,2,3), "abc" = c(3,2,1)); print(a)
  a abc
1 1   3
2 2   2
3 3   1

Maintenant, je supprime a$a du data.frame

> a$a <- NULL; print(a)
  abc
1   3
2   2
3   1

Comme prévu, je n'ai que abc colonne dans mon data.frame. Mais la partie étrange commence lorsque j'essaye de référencer la colonne supprimée a.

> print(a$a)
[1] 3 2 1
> print(is.null(a$a))
[1] FALSE

Il semble que R renvoie la valeur de a$abc au lieu de NULL.

Cela se produit lorsque le début du nom de la colonne restante correspond exactement au nom de la colonne supprimée.

Est-ce un bug ou est-ce que je rate quelque chose ici?

1
Sergey 24 janv. 2017 à 17:48

4 réponses

Meilleure réponse

Bien que votre question exacte ait déjà reçu une réponse dans les commentaires, une alternative pour éviter ce comportement consiste à convertir votre data.frame en tibble, qui est une version allégée d'un data.frame, sans nom de colonne munging , parmi autres choses:

library(tibble)
df_t <- as_data_frame(a)
df_t
# A tibble: 3 × 1
    abc
  <dbl>
1     3
2     2
3     1
> df_t$a
NULL
Warning message:
Unknown column 'a' 
0
mtoto 24 janv. 2017 à 15:19

Cela vaut peut-être la peine de le souligner (car il ne s'est pas présenté sur le précédent question connexe) que ce comportement de correspondance partielle est potentiellement une raison pour éviter d'utiliser '$', sauf comme un raccourci pratique lorsque vous utilisez R de manière interactive (au moins, c'est une raison d'être prudent en utilisant il).

La sélection d'une colonne via dat[,'ind'] si vous connaissez le nom de la colonne, mais pas la position, ou via dat[,3] si vous connaissez la position, est souvent plus sûre car vous ne vous heurterez pas à la correspondance partielle .

4
Community 23 mai 2017 à 11:53

De l'aide. ? $

name: Une chaîne de caractères littérale ou un nom (éventuellement contre-coté). Pour l'extraction, cela correspond normalement (voir sous «Environnements») partiellement aux noms de l'objet.

C'est donc le comportement normal car le nom correspond partiellement. Voir? Pmatch pour plus d'informations sur la correspondance partielle.

À votre santé

8
Luciano Selzer 8 juin 2011 à 15:44

À partir de la définition du langage R [section 3.4.1 p. 16-17] -

https://cran.r-project.org/doc/manuals/r-release/R-lang.pdf

Caractère : les chaînes de i sont comparées à l'attribut names de x et les entiers résultants sont utilisés. Pour [[et $ la correspondance partielle est utilisée si la correspondance exacte échoue, donc x $ aa correspondra à x $ aabb si x ne contient pas de composant nommé "aa" et "aabb" est le seul nom qui a le préfixe "aa". Pour [[, la correspondance partielle peut être contrôlée via l'argument exact qui vaut par défaut NA indiquant que la correspondance partielle est autorisée, mais devrait entraîner un avertissement quand cela se produit. La définition d'exact sur TRUE empêche une correspondance partielle, une valeur FALSE l'autorise et n'émet aucun avertissement. Notez que [nécessite toujours une correspondance exacte. La chaîne "" est traitée spécialement: elle indique "pas de nom" et ne correspond à aucun élément (pas même ceux sans nom). Notez que la correspondance partielle n'est utilisée que lors de l'extraction et non lors du remplacement.

0
Travis Gaddie 24 janv. 2017 à 14:58