Qu'est-ce qu'un bon usage de la fonction 'commentaire' dans R?

35

Je viens de découvrir la commentfonction dans R. Exemple:

x <- matrix(1:12, 3,4)
comment(x) <- c("This is my very important data from experiment #0234",
                "Jun 5, 1998")
x
comment(x)

C'est la première fois que j'utilise cette fonction et je me demandais quelles en sont les utilisations courantes / utiles. Puisqu'il est assez difficile de rechercher "R comment" dans google et de trouver des résultats pertinents, j'espérais que quelqu'un ici pourrait partager son expérience.

Tal Galili
la source
3
Je ne pense pas que cette question doive vraiment être une CW. C'est limite, mais ce n'est pas si mal.
csgillespie
bonne information! (Le paquet de séries temporelles 'xts' a cette fonctionnalité de métadonnées similaire.)
doug
2
Cette question a été suggérée comme conclusion: si la question est interprétée de manière large (et notez qu’aucune des réponses n’est spécifique à R), c’est vraiment une question de savoir quand et pourquoi on voudrait étiqueter des colonnes de données. Ce type de problème de gestion des données fait clairement partie des pratiques habituelles de la statistique, il en va de même pour le sujet.
Silverfish

Réponses:

15

Pour seconder @Gavin, Frank Harrell a mis au point des méthodes efficaces pour gérer data.frame annoté en R dans son package Hmisc . Par exemple, les fonctions label()et units()permettent d'ajouter des attributs dédiés aux objets R. Je les trouve très utiles pour produire un résumé de data.frame (avec, par exemple describe()).

Un autre moyen utile d'utiliser un tel attribut supplémentaire consiste à appliquer un horodatage sur un jeu de données. J'ajoute également un attribut pour des éléments tels que la graine aléatoire, le numéro de pli (lorsque j'utilise la validation croisée k-kold ou LOO).

chl
la source
14

Une chose que je me trouve souvent dans mes scripts R pour une tâche d'analyse de données particulière est d'inclure des commentaires dans le script concernant les unités de variables dans mes trames de données. Je travaille avec des données environnementales et les chimistes et les écologistes semblent aimer utiliser un large éventail d’unités différentes pour les mêmes choses (mg L vs mu eq L , etc.). Mes collègues stockent généralement ces informations dans la ligne située immédiatement en dessous des noms de colonnes dans les feuilles Excel.-1-1

Je verrais comment()comme un bon moyen de joindre ces informations à un bloc de données pour référence future.

Rétablir Monica - G. Simpson
la source
2
La solution standard consiste à inclure un champ pour les unités de mesure, afin que l'ordinateur puisse être programmé pour convertir tous les résultats numériques en unités communes (spécifiques à un paramètre). Enfouir ces informations cruciales dans les commentaires rend la mise en œuvre de cette capacité difficile, voire impossible.
whuber
2
@whuber mais R n'a pas une telle construction dans ses objets de base et je ne veux pas écrire une pile complète de méthodes S4 pour reproduire des trames de données qui véhiculent les informations d'unité. Notez que ce comment()ne sont pas des commentaires dans le code. Il attache un attribut spécifique à l'objet qui peut être un vecteur, un élément par colonne du cadre de données contenant les informations sur les unités. Il est facile d'extraire cette information, donc je ne vois pas pourquoi mettre en œuvre quoi que ce soit serait difficile ou impossible?
Réintégrer Monica - G. Simpson
1
Gavin, je suggère quelque chose de beaucoup plus simple. Par exemple, si parfois les concentrations de sélénium sont enregistrées en mg / L et d'autres fois en meq / L, vous pouvez facilement sélectionner toutes les occurrences de cette dernière et multiplier la concentration par le facteur approprié pour la convertir en mg / L. Cependant - ceci peut être la source de votre objection - Rn’est certainement pas le bon endroit pour gérer des bases de données et exécuter des processus de ce type, même s’il est capable de le faire. Il est préférable de le compléter par un bon système de gestion de base de données pour ce type de travail.
whuber
4
Amen à cela! comment()et autres sont pratiques pour les notes ad hoc et les informations, mais un système approprié est nécessaire pour le traitement des données à plus grande échelle. Il est intéressant de noter que nous devons maintenant régler ce problème au sein du groupe de recherche et du cabinet de conseil pour lesquels je travaille en ce qui concerne nos données sur la chimie et que nous devons les mettre dans une base de données appropriée.
Rétablir Monica - G. Simpson
8

Des installations similaires existent dans d'autres packages, tels que la commande -notes- dans Stata . Nous l'utilisons pour documenter les détails complets d'une variable, par exemple les détails d'un test pour une mesure biochimique ou la formulation exacte de la question posée pour les données du questionnaire. C’est souvent trop d’informations pour le nom ou l’étiquette de la variable, l’une ou les deux étant affichées dans le résultat de chaque analyse impliquant la variable et il est donc préférable de la maintenir raisonnablement courte.

un arrêt
la source
4

L’une des choses que je me découvre souvent est le suivi des commandes utilisées pour générer des données et des objets, et j’ai trouvé que le commentaire était un outil utile à cet égard.

'Matched.call.data' et 'generate.command.string' font l'affaire. Pas parfait, mais utile et utile pour 'comment ()'. :)

# Comments only accept strings...
# Substituting the escaped quotes ('\"') makes it prettier.
generate.command.string <- function( matched.call.data )
{
  command.string <- as.character( bquote( .( list( matched.call.data ) ) ) )
  sapply( bquote( .(command.string) ),
                  USE.NAMES=FALSE,
                  function( x )
                    gsub( "\\\"", "\'", as.list( match.call() )$x )[[2]] )
}

# Some generating function...
generate.matrix <- function( nrows, ncols, data=NA ) {
  # Some generated object
  mat <- matrix( data= data, nrow= nrows, ncol= ncols )

  matched.call.data <- do.call( "call",
                                c( list( as.character( match.call()[[1]] ) ),
                                lapply( as.list( match.call() )[-1], eval ) ) )
  comment( mat ) <- c( Generated= date(),
                       Command = generate.command.string( matched.call.data ) )

  mat
}

# Generate an object with a missing argument.
emptyMat <- generate.matrix( nrows=2, ncols=2 )
comment( emptyMat )

# Generate without formally stating arguments.
dataMat <- generate.matrix( 2, 2, sample(1:4, 4, replace= TRUE ) )
comment( dataMat )

# And with a longer command.
charMat <- generate.matrix( 3, 3,
                  c( 'This', 'is', 'a', 'much', 'longer',
                     'argument', 'section', 'that', 'wraps') )
comment( charMat )

# And with a variable.
myData <- c( 'An', 'expanded', 'command', 'argument')
charMat2 <- generate.matrix( 2, 2, myData )
comment( charMat2 )

# Create a new object from an original command.
Sys.sleep(1)
emptyMat2 <- eval( parse( text= comment( emptyMat )[['Command']] ) )
dataMat2 <- eval( parse( text= comment( emptyMat )[['Command']] ) )

# Check equality of the static matrices.
identical( emptyMat, emptyMat2 )

# The generation dates are different.
all.equal( emptyMat, emptyMat2, check.attributes= FALSE )
comment( emptyMat )['Generated'] <- NA
comment( emptyMat2 )['Generated'] <- NA
identical( emptyMat, emptyMat2 )

# Command argument structure still works too.
str( as.list( match.call(
  generate.matrix, parse( text=comment( charMat2 )[[ 'Command' ]] ) ) )[-1] )
Thell
la source
2

Permettez-moi de suggérer ma solution générale à la gestion des objets dans R: le repopackage. En l'utilisant, vous pouvez affecter à chaque variable un nom long, une description, un ensemble de balises, une URL distante, des relations de dépendance et également attacher des figures ou des fichiers externes génériques. Par exemple, le code source peut être stocké en tant qu'élément de référentiel et attaché aux ressources qu'il produit. Recherchez la dernière version stable sur CRAN ( install.packages("repo")) ou les derniers développements sur github . Un aperçu rapide ici . J'espère que ça aide.

Francesco Napolitano
la source