How to introduce object assignment when teaching R?

I'm working on some teaching materials to introduce R to my colleagues and I'm having trouble describing the concept of object assignment in a succinct way. I think because it is so fundamental, it's been hard for me to come up with a good way to introduce the idea to people who don't have any programming experience. Most of the people I will be teaching have lots of experience in Excel and SQL (some with a little SPSS), but little to none in other programming languages.

Can anyone point me to some good resources for introducing assignment? Any ideas for teaching assignment conceptually?

2 Likes

I don't see why this should be too difficult. I think the best way to get them to wrap their heads around it is simply pulling up the R console and demonstrating some basics.

> 1+1
[1] 2
> 2*3
[1] 6
> sqrt(25)
[1] 5
> x <- sqrt(25)
> x
[1] 5

Go through a few object types, vector, string, dataframe etc. It's pretty intuitive that object assignment is just giving a name to this thing we call an object. Explain the attributes of an object, is this an object? Why or why not. Showing is better than telling.

I think one of the interesting "features" in R is that you use (or at least it is considered good practice) to assign objects to symbols using <- rather than =. The latter is often interpreted as checking for equality (e.g., in SQL) which is fundamentally different from assignment. The way I think about it is that assignment is using a symbol on the left hand side of <- as the key for some object on the right hand side of the <- (e.g., a data frame), in a way it allows us to access that object, until (if) we reassign it. On a deeper level it also has to do with environments, as x in one environment can be very different from an x in a different environment, but I guess that something to mention further down the line - even though this becomes very relevant once you might want to introduce functions which create their temporary environments while executing.

By the way, I just decided to test something out and interestingly you can do the following:

"x" <- 1
"x" + 1 
#> Error in "x" + 1: non-numeric argument to binary operator

Created on 2019-09-08 by the reprex package (v0.3.0)
The first line executes without an error and R interprets "x"as a symbol in the assignment, but when I try "x" + 1, "x" is intepreted as string literal and an error is raised. Wouldn't it be more "correct" if an error is thrown already at "x" <- 1 as we shouldn't be able to assign a value to a string literal?

1 Like

Thanks for your response. The two main stumbling blocks that I have encountered are:

  1. The idea that an object can be "anything." A value, a vector, a data frame, a function, a model, a plot, etc., etc. Coming from non-coding data analysis environments, this can be confusing as you might think about your dataset as an object, but the other things an object can be in R don't necessarily have analogs outside of the programming context.

  2. To modify an object, you must assign it to "save" the changes. For folks coming from Excel or SPSS, executing code changes the "data," whereas in R and the tidyverse specifically, executing code (most often) just prints output. For example, it would be reasonable to expect that running the following code would add a new column to the iris dataset. "Look, I can see the new column right there!"

library(dplyr)
iris %>% 
  mutate(sepal_ratio = Sepal.Length / Sepal.Width) %>% 
  head()
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species sepal_ratio
#> 1          5.1         3.5          1.4         0.2  setosa    1.457143
#> 2          4.9         3.0          1.4         0.2  setosa    1.633333
#> 3          4.7         3.2          1.3         0.2  setosa    1.468750
#> 4          4.6         3.1          1.5         0.2  setosa    1.483871
#> 5          5.0         3.6          1.4         0.2  setosa    1.388889
#> 6          5.4         3.9          1.7         0.4  setosa    1.384615

But of course since we didn't assign this output anywhere, iris hasn't changed:

iris %>% 
  head()
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1          5.1         3.5          1.4         0.2  setosa
#> 2          4.9         3.0          1.4         0.2  setosa
#> 3          4.7         3.2          1.3         0.2  setosa
#> 4          4.6         3.1          1.5         0.2  setosa
#> 5          5.0         3.6          1.4         0.2  setosa
#> 6          5.4         3.9          1.7         0.4  setosa
1 Like