2010-09-18 8 views
3

Je pense que j'obtiens une erreur de cadrage lorsque j'utilise transformBy(), une partie du paquet doBy pour R. Voici un exemple simple du problème :Erreur de définition (statistique) en utilisant transformBy(), partie du paquet doBy

> library(doBy) 
> 
> test.data = data.frame(
+ herp = c(1,2,3,4,5), 
+ derp = c(2,3,1,3,5) 
+) 
> 
> transformData = function(data){ 
+ 
+ five = 5 
+ 
+ transformBy(
+ ~ herp, 
+ data=data, 
+ sum=herp + derp + five 
+ ) 
+ } 
> 
> transformData(test.data) 
Error in eval(expr, envir, enclos) : object 'five' not found 

Quand je lance transformBy() dans un sous-champ (portée non globale) aucune variable ou fonctions locales semblent être disponibles pour une utilisation dans transformBy. Si, au contraire, je définis globalement ces variables ou fonctions, elles deviennent disponibles. Voici un exemple légèrement modifié qui fonctionne:

> library(doBy) 
> 
> test.data = data.frame(
+ herp = c(1,2,3,4,5), 
+ derp = c(2,3,1,3,5) 
+) 
> 
> five = 5 
> 
> transformData = function(data){ 
+ transformBy(
+ ~ herp, 
+ data=data, 
+ sum=herp + derp + five 
+ ) 
+ } 
> 
> transformData(test.data) 
    herp derp sum 
1 1 2 8 
2 2 3 10 
3 3 1 9 
4 4 3 12 
5 5 5 15 

Suis-je mal compris quelque chose sur la façon dont transformBy est censé fonctionner ou est quelque chose de cassé?

Versions:

  • ubuntu: 8,04 (x64)
  • R: 2.10.1
  • DOBY: 4.0.5
+0

Je ne sais pas exactement ce que vous essayez de faire ici mais, si vous voulez juste ajouter des colonnes: test.data <- data.frame (herp = test.data $ herp, derp = test.data $ derp, sum = test.data $ herp + test.data $ derp + 5) –

+0

@Brandon: voir? transformBy.Votre code n'est pas équivalent à la question OP –

Répondre

2

Ceci est clairement documenté dans la page d'aide? TransformBy, et donc pas un bug.

Détails:

The ... arguments are tagged vector expressions, which are 
evaluated in the data frame data. The tags are matched against 
names(data), and for those that match, the value replace the 
corresponding variable in data, and the others are appended to 
data. 

Il suffit de faire l'objet « cinq » une partie des data.frame « données », et cela fonctionnera comme prévu. Actuellement, la fonction essaie de évaluer "cinq" dans le "data" data.frame, qui échoue bien sûr.

+0

Merci pour l'explication. –

2

Ceci est un problème qui se pose dans une variété de façons. Apparemment, quelque chose d'étrange se passe avec le scoping dans R.

edit: Ce n'est pas la portée dans R qui fonctionne différemment de ce que j'attendais naïvement, mais celui de transformBy(). Voir la réponse d'Erik.

je contourner en affectant un environnement temporaire dans l'environnement mondial, quelque chose comme:

transformData = function(data){ 

    temp_env <<- new.env(hash=T) #hashed environment for easy access 
    temp_env$five = 5 

    out <- transformBy(
    ~ herp, 
    data=data, 
    sum=herp + derp + temp_env$five 
) 
    rm(temp_env,envir=.GlobalEnv) # cleanup 
    return(out) 
} 
+0

Parlez-moi de ça. –

2

Je considère ceci comme un bug dans la fonction transformBy. Si vous regardez la source de transformBy, il crée une sous-fonction appelée transform2 qui évalue le dernier argument en premier dans le contexte de la base de données, avec le parent.frame() comme environnement englobant. Il appelle ensuite lapply au transform2.

Puisque R utilise la sémantique lexicale (voir http://cran.r-project.org/doc/manuals/R-intro.html#Scope), la hiérarchie de portée effective est alors datalapply alors mondiale. Je pense que la bonne solution est d'ajouter une déclaration de la forme pf <- parent.frame() en dehors de la définition transform2, puis référence pf dans l'instruction eval.