0

I want to just name these strings "Agra" and "huge" as place and adjective in the simplest way possible.

First I tried this

> args <- list(place <- "Agra", adjective <- "huge")
> args[[1]]
[1] "Agra"
but
> args[["place"]]
NULL
and
> place
[1] "Agra"

here only place object is created but the string is not named

whereas

> args <- list(place = "Agra", adjective = "huge")
here 
>args[[1]]
"Agra"
> args[["place"]]
[1] "Agra"
> place
[1] "Agra"

Although the second one works but objects are still created. why there is a difference in the outputs of the two methods? how can I give names without creating objects?

Ankit
  • 394
  • 1
  • 4
  • 16

1 Answers1

3

It is because <- and = are not the same. For (just about) every purpose except when used inside a function call, <- and = are the same. If you want to pass a named argument, you have to use = not <-. myFunction(X <- expression) will evaluate expression and save the result into the (global) variable X, and put the result as the first (unnamed) argument to myFunction. Contrast to myFunction(X = expression) which pass the expression as the named X argument to myFunction and will not create a (global) variable X.

My explanation is a little garbled - I highly recommend reading ?'<-' (the helpfile for <- and =) which is clearer.


In the first one:

args <- list(place <- "Agra", adjective <- "huge")

R evaluates place <- "Agra" in the global environment, which returns "Agra". It also evaluates adjective <- "huge" in the global environment similarly, returning "huge". Then it places the results ("Agra" and "huge") into the list() call as unnamed arguments, so essentially what you are doing is

place <- "Agra"
adjective <- "huge"
args <- list("Agra", "huge")

That is why you get global variables, and the args list has no names. If this is what you want, you should use the long form not the short form to write it. Using the first form could lead to unexpected or confusing side-effects.

In the second option

args <- list(place = "Agra", adjective = "huge")

it is simply passing the named argument "place" with value "Agra", and the named argument "adjective" with value "huge". Since list() uses argument names as list names, that's why you get a named list. Also, this will not create global variables place and adjective.

mathematical.coffee
  • 55,977
  • 11
  • 154
  • 194
  • 2
    Another way to phrase one of those key concepts, "`=` acts as an assignment operator if and only if it is used outside of a function call" – Benjamin Oct 17 '16 at 13:58
  • just one doubt, in the second method if `place` is not a global variable then how it is accessible outside function call? – Ankit Oct 17 '16 at 15:19
  • 1
    @Ankit it isn't - it's still there from your first line. If you put `rm(list=ls())` in between to clear the workspace, you can confirm the second line will not create any variables. – mathematical.coffee Oct 17 '16 at 23:00