Warning: Error in <-: 'names' attribute must be the same length as the vector

tidyr
rstudio

#1

I'm on MAC Rstudio version Version 1.1.453

I'm getting this error;

> runApp()
> Listening on http://127.0.0.1:4793
> Warning: Error in <-: 'names' attribute [8] must be the same length as the vector [7]
>   48: structure
>   47: server [/Users/markloessi/Data/shinny/googlebubble71820/server.R#11]
> Error in attributes(.Data) <- c(attributes(.Data), attrib) : 
>   'names' attribute [8] must be the same length as the vector [7]

Here's what I'm doing;
I'm looking at incorporating my own data into this GoogleChart implementation.

http://shiny.rstudio.com/gallery/google-charts.html
I am using convert("healthexp.Rds", "healthexpcsv4.xlsx") to turn RDS in XLS so I can then edit and incorporate my own data. Ultimately I'm looking to use very similar data (charging data over time) which will benefit from the animation in this example.

After converting the working RDS file to XLS if I then convert that new XLS right back to RDS (not opening XLS to edit) that new RDS file works fine. If, I open the XLS, change some of the names of countries and then save (no column changes or header changes, etc....) and convert, THAT new RDS gives me the above error.

I've worked out that some part of the saving of the XLS must be changing some attribute or parameter of the fields such that when the FACTOR'ing process occurs something is amiss (sorry not accurate language most likely).

This bit;

> data$Region <- as.factor(data$Region)

Then used here;

> shinyServer(function(input, output, session) {
>   
>   # Provide explicit colors for regions, so they don't get recoded when the
>   # different series happen to be ordered differently from year to year.
>   # http://andrewgelman.com/2014/09/11/mysterious-shiny-things/
>   defaultColors <- c("#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477")
>   series <- structure(
>     lapply(defaultColors, function(color) { list(color=color) }),
>     names = levels(data$Region)
>   )

I dug around a bit on the internet, and on community.rstudio.com where I found some tidyr bits about something similar but I couldn't equate to what was going on here, although it sure looks similar.


#2

From the error message, it seems something along the lines of this is happening:

my_vec = 1:7
my_vec
[1] 1 2 3 4 5 6 7
LETTERS[1:8]
[1] "A" "B" "C" "D" "E" "F" "G" "H"
names(my_vec) = LETTERS[1:8]
Error in names(my_vec) = LETTERS[1:8] : 
  'names' attribute [8] must be the same length as the vector [7]

I.e. you are trying to assign more names, than there are elements in a vector


#3

So, in the process I described above I'm not changing anything about the columns or names of the columns. I'm simply opening the file and changing the name of a country like 'Albania' to 'Mark' and saving. I'm not even changing the number of rows in the file. Because of this I'm having a hard time reconciling that I'm doing any kind of 'assigning' of names that would be any different than what the file started with.

That said clearly something is happening along those lines, I'm just not sure how to see what it is or how I might 'fix' it once/when I convert back to RDS.


#4

It can help when debugging this sort of thing to run bits of code on their own and see what happens. The str() function, which shows you the structure of objects (and some other metadata) is also a useful tool.

To apply those principles here:

defaultColors <- c("#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477")
str(defaultColors)
#> chr [1:7] "#3366cc" "#dc3912" "#ff9900" "#109618" "#990099" "#0099c6" ...

str(lapply(defaultColors, function(color) { list(color=color) }))
#> List of 7
#>  $ :List of 1
#>   ..$ color: chr "#3366cc"
#>  $ :List of 1
#>   ..$ color: chr "#dc3912"
#>  $ :List of 1
#>   ..$ color: chr "#ff9900"
#>  $ :List of 1
#>   ..$ color: chr "#109618"
#>  $ :List of 1
#>   ..$ color: chr "#990099"
#>  $ :List of 1
#>   ..$ color: chr "#0099c6"
#>  $ :List of 1
#>   ..$ color: chr "#dd4477"

So defaultColors is a vector of 7 values. Then the lapply() line is converting this into a somewhat complex nested list (presumably because that’s the kind of object other functions expect), but it still has 7 main elements.

The key line I can’t run, because I don’t have access to your data, is:

str(levels(data$Region))

But I suspect that what you’ll find is that data$Region has 8 levels. So when the code tries to assign names to the nested list object it made out of defaultColors based on the levels of data$Region, it doesn’t know how to do it because it has 8 names for 7 list elements. (Shorter version: what @Leon said! :grin: )

Changing the country names changes the data. Levels of a factor variable are the unique values of that variable. So in changing some country names, it looks like you went from 7 unique values to 8 unique values. So to adapt this code to work with the changes you made to the data, you’ll need to supply an eighth color value in defaultColors.


#5

Sweet!

OK, yes, shorter version what @Leon said :smiley:

Thank you so much for all the education. When I went back through the process in detail, I'd edited the 'REGION' list inadvertently adding an additional region OMG!

Once fixed my new RDS works.