mtcars_basic

Published

April 5, 2024

Modified

April 5, 2024

A frequent problem occurs when trying to access columns inside a data.frame.

head(mtcars)
....->                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
....-> Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
....-> Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
....-> Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
....-> Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
....-> Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
....-> Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

mtcars[1:5, c("hp")]
....-> [1] 110 110  93 110 175

But using just col name fails.

mtcars[1:5, hp]
....-> Error in eval(expr, envir, enclos): object 'hp' not found

The reason as explained in many places, such as dplyr ….., is mtcars exisits in the environment, but not hp.

hp
....-> Error in eval(expr, envir, enclos): object 'hp' not found

Again this is explained in many places, along with several ways to fix, for example.

with(mtcars, hp)
....->  [1] 110 110  93 110 175 105 245  62  95 123 123 180 180 180 205 215 230  66  52
....-> [20]  65  97 150 150 245 175  66  91 113 264 175 335 109

Of course, R’s help also explains this but you must be comfortable with terms like environment , expression and parent and what constructing an environment with data means.

?with

Here is my own take. It is same as above, but I find this way clearer.

Let’s check what is current globalenv() the the environment. Then packages attached to search path.

ls()
....-> [1] "has_annotations"
search()
....-> [1] ".GlobalEnv"        "package:stats"     "package:graphics" 
....-> [4] "package:grDevices" "package:utils"     "package:datasets" 
....-> [7] "package:methods"   "Autoloads"         "package:base"

For our purposes, note there is no hp

ls(base)
....-> Warning in ls(base): 'base' converted to character string
....-> Error in as.environment(pos): no item called "base" on the search list
ls("package:base") |> grep(pattern=c("mtcars"))
....-> integer(0)

Attach mtcars to search path

attach(mtcars)
search()
....->  [1] ".GlobalEnv"        "mtcars"            "package:stats"    
....->  [4] "package:graphics"  "package:grDevices" "package:utils"    
....->  [7] "package:datasets"  "package:methods"   "Autoloads"        
....-> [10] "package:base"

Now, can find hp

hp
....->  [1] 110 110  93 110 175 105 245  62  95 123 123 180 180 180 205 215 230  66  52
....-> [20]  65  97 150 150 245 175  66  91 113 264 175 335 109

Why? col names are in environment one level up from globalenv()

ls(parent.env(globalenv()))
....->  [1] "am"   "carb" "cyl"  "disp" "drat" "gear" "hp"   "mpg"  "qsec" "vs"  
....-> [11] "wt"

This will add mtcars into globalenv(), but not change search()

# This puts data in globalenv()
data(mtcars)
ls()
....-> [1] "has_annotations" "mtcars"
search()
....->  [1] ".GlobalEnv"        "mtcars"            "package:stats"    
....->  [4] "package:graphics"  "package:grDevices" "package:utils"    
....->  [7] "package:datasets"  "package:methods"   "Autoloads"        
....-> [10] "package:base"

Remove mtcars

rm(mtcars)
ls()
....-> [1] "has_annotations"
mtcars[1:5, ]
....->                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
....-> Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
....-> Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
....-> Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
....-> Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
....-> Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
ls()
....-> [1] "has_annotations"