Error Preventing Knitting

Thanks, that's helpful! When I run your code on my computer, the same line throws an error (no knitting involved). That makes sense because, in fact, natenvir is not defined as an object anywhere in your code. Here's what I suspect is going on:

Often when you've been working on something for a while, there will be lots of random R objects littering your workspace that you created (on purpose or accidentally) while you were experimenting with bits of code. When knitr starts rendering, it runs in a fresh session with its own workspace — it can only "see" objects that you create in the code you give it. So when you're getting an "object not found" error while knitting that you don't get while running your code outside of knitr, it's a clue that it's time to clear up the clutter because knitr just found a bug in your code :beetle: .

It's a good idea to clear your workspace (= "global environment") and start a new R session periodically while you're working to prevent this kind of bug from creeping in. In RStudio, you can use the little broom icon on the Environment pane to clear the workspace, and you can restart R from the Session menu. If you do this and try running your code again, I think you'll find that you get an error at the same spot without trying to knit anything.

OK, so how to fix your code? TL;DR: Since the names in s3 came from y5, I would just use:

barplot(s3, legend = levels(y5$natenvir), args.legend = list(x = 'bottomright'))
But I really want to get the names from s3!

To pull the names directly from s3, you'll need to use different syntax because s3 is not a data frame :open_mouth: As you can read in the documentation, table() returns an array, which is a different data structure that works differently. You can check this yourself by running:

is.data.frame(s3)
is.array(s3)

table() doesn't preserve any information about the names of the variables that were used to make the table, so the term natenvir means nothing to s3. The names for the table dimensions are stored in an attribute called dimnames (which is accessed with the function dimnames()). The dimnames are stored as a list of character vectors, one for each dimension of the table. You can see all this by examining the result of str(s3). natenvir corresponds to the first dimension of s3 (the rows), so you would pull out those row names with:

dimnames(s3)[[1]]

Good luck with the class!

P.S. In this case, I was able to find the teaching dataset you're using by googling around, but in general it's a good idea to provide at least a small sample of the data you're working with when seeking help, so that other people have all the parts they need to quickly test out your code. Lots more info on best practices for sharing code to get help here.

1 Like