web-dev-qa-db-fra.com

Comment puis-je changer le nom d'un bloc de données

Dans une situation récurrente, je mets une valeur au sommet d'un long jeu de code R utilisé pour sous-définir un ou plusieurs trames de données. Quelque chose comme ça:

city_code <- "202"

À la fin du processus, j'aimerais enregistrer les résultats dans un bloc de données nommé, par exemple, en ajoutant le "code ville" à un stub commun.

city_results <- paste("city_stats", city_code, sep = "")

Mon problème est que je ne peux pas comprendre comment renommer le bloc de données résultant en la valeur de "city_results". Beaucoup d'informations sur la façon de renommer les colonnes d'un cadre de données, mais pas sur le renommage du cadre de données lui-même. Sur la base d'une réponse proposée, voici une clarification:

Merci, @ mike-sage. Utile pour étudier Advanced R de Hadley avec un problème concret en main.

library(dplyr)
gear_code <- 4
gear_subset <- paste("mtcars_", gear_code, sep = "")
mtcars_subset <- mtcars %>% filter(gear == gear_code)
head(mtcars_subset)
write.csv(mtcars_subset, file = paste(gear_subset, ".csv", sep = ""))

Cela me permet d’écrire le sous-ensemble dans un fichier csv portant le nom approprié. Cependant, votre suggestion fonctionne assez bien, mais je ne peux pas, par exemple, faire référence à data.frame avec le nouveau nom:

assign(gear_subset, mtcars_subset)
head(gear_subset)
6
John David Smith

La vérité est que les objets dans R n'ont pas de noms en tant que tels. Il existe différents types d’environnements, y compris un environnement global pour chaque processus. Ces environnements ont des listes de noms, qui pointent vers divers objets. Deux noms différents peuvent désigner le même objet. Ceci s’explique le mieux à ma connaissance dans le chapitre sur les environnements du livre Hadley Wickhams Advanced R http://adv-r.had.co.nz/Environments.html

Il n'y a donc aucun moyen de changer le nom d'un bloc de données, car il n'y a rien à changer. 

Mais vous pouvez faire pointer un nouveau nom (tel que newname) sur le même objet (dans votre cas un objet de bloc de données) en tant que nom donné (tel que oldname) simplement en effectuant:

   newname <- oldname

Notez que si vous modifiez l'une de ces variables, une nouvelle copie sera créée et les références internes ne seront plus les mêmes. Ceci est dû à la sémantique de "Copie sur modification" de R. Voir ce post pour une explication: En quoi consiste exactement la sémantique de copie sur modification dans R, et où se trouve la source canonique?

J'espère que cela pourra aider. Je connais la douleur. Les langages dynamiques et fonctionnels sont différents des langages statiques et procéduraux ...

Bien sûr, il est possible de calculer un nouveau nom pour un cadre de données et de l'enregistrer dans l'environnement à l'aide de la commande assign - et vous le cherchez peut-être. Cependant, y faire référence par la suite serait plutôt compliqué.

Exemple (en supposant que df est la base de données en question):

   assign(  paste("city_stats", city_code, sep = ""), df )

Comme toujours, voir l'aide de assign pour plus d'informations http://stat.ethz.ch/R-manual/R-devel/library/base/html/assign.html

Edit: En réponse à votre édition et divers commentaires sur les problèmes liés à l'utilisation de eval(parse(...), vous pouvez analyser le nom de la manière suivante:

head(get(gear_subset))
13
Mike Wise

Généralement, vous ne devriez pas générer par programme les noms des trames de données dans votre environnement global. C'est une bonne indication que vous devriez utiliser list pour vous simplifier la vie. Voir la FAQ Comment faire une liste de trames de données? pour de nombreux exemples et plus de discussion.

En utilisant votre exemple concret, je le récrirais de différentes manières.

library(dplyr)
gear_code <- 4
gear_subset <- paste("mtcars_", gear_code, sep = "")
mtcars_subset <- mtcars %>% filter(gear == gear_code)
head(mtcars_subset)
write.csv(mtcars_subset, file = paste(gear_subset, ".csv", sep = ""))

L’objectif semble être d’écrire un fichier CSV appelé gear_X.csv qui a le sous-ensemble mtcars avec gear == X. Vous ne devez pas garder un cadre de données intermédiaire, cela devrait aller:

gear_code <- 4
mtcars %>% filter(gear == gear_code) %>%
    write.csv(file = paste0('mtcars_', gear_code, '.csv'))

Mais vous le codez probablement de cette façon parce que vous voulez le faire pour chaque valeur de gear, et c’est ici que dplyr's group_by aide:

CSV pour tous les engrenages

mtcars %>% group_by(gear) %>%
  do(csv = write.csv(file = sprintf("mt_gear_%s.csv", .[1, "gear"]), x = .)

Cadres de données pour chaque niveau de vitesse:

Si vous voulez vraiment des objets de bloc de données individuels pour chaque niveau d’engrenage, il est préférable de les conserver dans une liste.

gear_df = split(mtcars, mtcars$gear)

Cela vous donne une list de trois trames de données, une pour chaque niveau de gear. Et ils sont déjà nommés avec les niveaux, alors pour voir le bloc de données avec toutes les lignes gear == 4, faites-le.

gear_df[["4"]]

Généralement, il est plus facile de travailler avec trois cadres de données flottants. Tout ce que vous voulez faire sur tous les cadres de données peut être fait en même temps avec une seule lapply, et même si vous voulez utiliser une boucle for, c'est plus simple que eval(parse()) ou get().

1
Gregor