web-dev-qa-db-fra.com

Dans R, obtention de l'erreur suivante: "tentative de répliquer un objet de type 'fermeture'"

J'essaie d'écrire une fonction R qui prend un ensemble de données et génère la fonction plot () avec l'ensemble de données lu dans son environnement. Cela signifie que vous n'avez plus besoin d'utiliser attach (), ce qui est une bonne pratique. Voici mon exemple:

mydata <- data.frame(a = rnorm(100), b = rnorm(100,0,.2))
plot(mydata$a, mydata$b) # works just fine

scatter_plot <- function(ds) { # function I'm trying to create
    ifelse(exists(deparse(quote(ds))),
        function(x,y) plot(ds$x, ds$y),
            sprintf("The dataset %s does not exist.", ds))
    }

scatter_plot(mydata)(a, b) # not working

Voici l'erreur que j'obtiens:

Error in rep(yes, length.out = length(ans)) : 
  attempt to replicate an object of type 'closure'

J'ai essayé plusieurs autres versions, mais elles me donnent toutes la même erreur. Qu'est-ce que je fais mal?

EDIT: je me rends compte que le code n'est pas trop pratique. Mon objectif est de mieux comprendre la programmation fonctionnelle. J'ai écrit une macro similaire en SAS, et j'essayais juste d'écrire son homologue en R, mais j'échoue. Je viens de prendre ceci comme exemple. Je pense que c'est un exemple assez simple et pourtant cela ne fonctionne pas.

15
mahin

Il y a quelques petits problèmes. ifelse est une fonction vectorisée, mais vous avez juste besoin d'un simple if. En fait, vous n'avez pas vraiment besoin d'un else - vous pouvez simplement lancer une erreur immédiatement si l'ensemble de données n'existe pas. Notez que votre message d'erreur n'utilise pas le nom de l'objet, il créera donc sa propre erreur.

Vous passez a et b au lieu de "a" Et "b". Au lieu de la syntaxe ds$x, Vous devez utiliser la syntaxe ds[[x]] Lorsque vous programmez (fortunes::fortune(312)). Si c'est ainsi que vous souhaitez appeler la fonction, vous devrez également déparer ces arguments. Enfin, je pense que vous voulez deparse(substitute()) au lieu de deparse(quote())

scatter_plot <- function(ds) {
  ds.name <- deparse(substitute(ds))
  if (!exists(ds.name))
    stop(sprintf("The dataset %s does not exist.", ds.name))
  function(x, y) {
    x <- deparse(substitute(x))
    y <- deparse(substitute(y))
    plot(ds[[x]], ds[[y]])
  }
}
scatter_plot(mydata)(a, b)
15
GSee