2017-02-13 3 views
1

Je suis encore un novice dans R, et je comprends encore l'évaluation paresseuse. Je lis un certain nombre de discussions sur SO (R functions that pass on unevaluated arguments to other functions), mais je ne suis toujours pas sûr.Argument non évalué dans R

Question 1:

Voici mon code:

f <- function(x = ls()) { 
    a<-1 
    #x ##without x 
    } 
f(x=ls()) 

Lorsque j'exécute ce code dire f(), rien ne retourne. Plus précisément, je ne vois pas la valeur de a. Pourquoi est-ce vrai?

Question 2:

De plus, je ne vois la valeur de a dans ce code:

f <- function(x = ls()) { 
    a<-1 
    x ##with x 
    } 
f(x=ls()) 

Lorsque j'exécute la fonction par f() je reçois:

[1] "a" "x" 

Pourquoi est-ce vrai? Quelqu'un peut-il m'aider s'il vous plaît?

+0

@BigDataSci - Merci pour votre réponse. Cela vous dérange-t-il d'expliquer cela un peu? Je n'ai pas très bien compris votre commentaire. – watchtower

+0

S'il n'y a pas d'instruction de retour explicite, la fonction renvoie la dernière ligne de l'exécution. Dans le premier cas: 'z <- f()' assignerait 'z' à la valeur 1. Dans le second cas, il renvoie la valeur de x, c'est-à-dire la sortie de' x <- ls() 'qui inclut' x' . – discipulus

Répondre

3

Question 1

Cela n'a rien à voir avec l'évaluation paresseuse.

Une fonction renvoie le résultat de la dernière instruction exécutée. Dans ce cas, la dernière déclaration était a <- 1. Le résultat de a <- 1 en est un. Vous pouvez par exemple faire b <- a <- 1 qui aurait pour conséquence b étant égal à 1. Ainsi, dans ce cas, vous fonction retourne 1.

> f <- function(x = ls()) { 
+ a<-1 
+ } 
> b <- f(x=ls()) 
> print(b) 
[1] 1 

L'argument x est utilisé nulle part, et donc ne joue aucun rôle.

Les fonctions peuvent renvoyer des valeurs de façon visible (par défaut) ou invisiblement. Pour retourner invisiblement la fonction invisible peut être utilisée. Un exemple:

> f1 <- function() { 
+ 1 
+ } 
> f1() 
[1] 1 
> 
> f2 <- function() { 
+ invisible(1) 
+ } 
> f2() 
> 

Dans ce cas f2 ne semble pas retourner quoi que ce soit. Cependant, il renvoie toujours la valeur 1. Ce que fait l'invisible, n'est rien imprimer quand la fonction est appelée et le résultat n'est assigné à rien. La pertinence de votre exemple est que a <- 1 retourne également de manière invisible. C'est la raison pour laquelle votre fonction ne semble rien retourner. Mais lorsqu'ils sont affectés à b ci-dessus, b obtient toujours la valeur 1.

Question 2

D'abord, je vais vous expliquer pourquoi vous voyez les résultats que vous voyez. Le a que vous voyez dans votre résultat, a provoqué du code précédent. Si nous nettoyons d'abord l'espace de travail, nous voyons seulement f. Cela a du sens lorsque nous créons une variable f (une fonction est également une variable dans R), puis effectuez une f.

> rm(list = ls()) 
> 
> f <- function(x = ls()) { 
+ a<-1 
+ x 
+ } 
> f(x=ls()) 
[1] "f" 

quoi correspond la fonction (au moins ce que vous attendez), si la première liste de toutes les variables ls() passer le résultat à la fonction x. Cette fonction renvoie ensuite x, qui est la liste de toutes les variables, qui est ensuite imprimée.

Comment cela peut être modifié pour montrer l'évaluation paresseuse au travail

> rm(list = ls()) 
> 
> f <- function(x) { 
+ a <<- 1 
+ x 
+ } 
> 
> f(x = ls()) 
[1] "a" "f" 
> 

Dans ce cas, l'attribution globale est utilisée (a <<- 1), ce qui crée une nouvelle a variable dans l'espace de travail global (pas de quelque chose que vous normalement vouloir faire).

Dans ce cas, on s'attendrait toujours à ce que le résultat de l'appel de fonction soit juste f. Le fait qu'il montre également a est causé par une évaluation paresseuse.

Sans évaluation paresseuse, il serait d'abord évaluer ls() (à ce moment-là seulement f existe dans l'espace de travail), copiez cela dans la fonction avec le nom x. La fonction renvoie ensuite x. Dans ce cas, le ls() est évalué avant la création de a.

Cependant, avec une évaluation paresseuse, l'expression ls() n'est évaluée que lorsque le résultat de l'expression est nécessaire. Dans ce cas, c'est la fonction qui revient et le résultat est imprimé. À ce moment l'environnement global a changé (a est créé), ce qui signifie que ls() montre également a.

(Ceci est aussi l'une des raisons pour lesquelles vous ne voulez pas changer les fonctions de l'espace de travail global à l'aide <<-.)

+0

Réponse fantastique. 2 questions: qu'est-ce que 'a << - 1'? ** Question 1 ** Il semble d'après votre réponse que «a» ne soit pas seulement «1» mais aussi évalué (c'est-à-dire «utilisé»). Correct? ** Question 2 ** J'ai légèrement modifié votre exemple pour inclure 'b <-2' comme dernière instruction. Cependant, maintenant je ne vois pas de 'a' renvoyé du tout. Code: 'rm (list = ls()); f <- fonction (x) {a << - 1; X; b <- 2}; c <-f (x = ls()); c' Pourquoi cela se passe-t-il? J'apprécierais vos pensées. Si nous vérifions la valeur de 'c', cela montrerait' 2'. Je me serais attendu à 'a' aussi bien. Je ne suis pas sûr de ce qui me manque ici. – watchtower

+1

@watchtower Première question: oui, plus précise: la valeur de 'a' est renvoyée par la fonction et affectée à' b'. –

+1

@watchtower Deuxième question: lorsque vous ajoutez 'b <- 2' à la fonction en tant que dernière instruction, le résultat de cette instruction est renvoyé par la fonction (identique à la première question originale). Par conséquent, la fonction renvoie la valeur de 'b' qui est' 2'. 'x' est utilisé dans la fonction mais n'est pas retourné, donc' ls() 'est évalué, mais le résultat n'est pas utilisé et n'est pas retourné. –