2

I am trying to use summarize, where the vector being summarized has names. The summarize function copies these names to the output, but the length is now wrong. When I try to format the resulting summary, the incorrect length of the names attribute throws an error.

In the example I really care about, the vector with names is the fitted.values from a glm model. I don't want the names, but they come for free. The toy example below uses mtcars.

``` r

library(tidyverse)
#> -- Attaching packages -------------------------------------------------------------------------------- tidyverse 1.2.1 --
#> v ggplot2 2.2.1     v purrr   0.2.4
#> v tibble  1.4.1     v dplyr   0.7.4
#> v tidyr   0.7.2     v stringr 1.2.0
#> v readr   1.1.1     v forcats 0.2.0
#> -- Conflicts ----------------------------------------------------------------------------------- tidyverse_conflicts() --
#> x dplyr::filter() masks stats::filter()
#> x dplyr::lag()    masks stats::lag()
# create a copy of mtcars, with the original mpg and a copy with names
namedmpg <- mtcars$mpg
attr(namedmpg, "names") <- row.names(mtcars)
MTCARS <- bind_cols(mtcars, namedmpg = namedmpg)

When I use the original mpg variable I get exactly what I want.

goodframe <- summarize(group_by(MTCARS, cyl), meanmpg = mean(mpg))
goodframe # gives exactly what we want
#> # A tibble: 3 x 2
#>     cyl meanmpg
#>   <dbl>   <dbl>
#> 1  4.00    26.7
#> 2  6.00    19.7
#> 3  8.00    15.1
format(goodframe$meanmpg) # formats fine
#> [1] "26.66364" "19.74286" "15.10000"

Now use the named mpg instead.

badframe <- summarize(group_by(MTCARS, cyl), meanmpg = mean(namedmpg))
badframe # seems to have what we want
#> # A tibble: 3 x 2
#>     cyl meanmpg
#>   <dbl>   <dbl>
#> 1  4.00    26.7
#> 2  6.00    19.7
#> 3  8.00    15.1
format(badframe$meanmpg) # throws an error
#> Error in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, : 'names' attribute [32] must be the same length as the vector [3]
names(badframe$meanmpg) # the original names, which are now too many
#>  [1] "Mazda RX4"           "Mazda RX4 Wag"       "Datsun 710"         
#>  [4] "Hornet 4 Drive"      "Hornet Sportabout"   "Valiant"            
#>  [7] "Duster 360"          "Merc 240D"           "Merc 230"           
#> [10] "Merc 280"            "Merc 280C"           "Merc 450SE"         
#> [13] "Merc 450SL"          "Merc 450SLC"         "Cadillac Fleetwood" 
#> [16] "Lincoln Continental" "Chrysler Imperial"   "Fiat 128"           
#> [19] "Honda Civic"         "Toyota Corolla"      "Toyota Corona"      
#> [22] "Dodge Challenger"    "AMC Javelin"         "Camaro Z28"         
#> [25] "Pontiac Firebird"    "Fiat X1-9"           "Porsche 914-2"      
#> [28] "Lotus Europa"        "Ford Pantera L"      "Ferrari Dino"       
#> [31] "Maserati Bora"       "Volvo 142E"

So I have to do something to get the summary in a form usable for further processing. Here is one hack.

format(badframe$meanmpg + 0) # a real hack, but seems to work

Of course there is always the old fashioned way

stillgood <- with(MTCARS, aggregate(namedmpg, list(cyl), mean))
stillgood
#>   Group.1        x
#> 1       4 26.66364
#> 2       6 19.74286
#> 3       8 15.10000
format(stillgood$x) # works
#> [1] "26.66364" "19.74286" "15.10000"

    ```

I am not sure if the situation is a bug or a feature. IMHO it should be documented either way.

In addition to the hack above, I could kill the names before the summarize. But I might want them someday.

Is there a better way?

1 Answer 1

2

We could wrap with unname if that is acceptable

format(unname(badframe$meanmpg) )
#[1] "26.66364" "19.74286" "15.10000"
Sign up to request clarification or add additional context in comments.

1 Comment

I like your suggestion, because it uses a standard R function designed for just this purpose. (As opposed to my hack.) I should have found this myself. I still am hoping to hear from a tidyverse person about the summarize function itself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.