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 <<-
.)
@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
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