rtidyverse

set_names() returns "character" not "tbl_df, tbl, data.frame"


Unexpected output of set_names()

Any ideas why?

library(tidyverse)

l1 <-  # Small list of short tibbles
diamonds |> 
  group_split(cut) |> 
  map(~ .x |> slice(1:2)) |> 
  head(2)

l1 |> # Trying to name them based on their class, but the result is "character" which is wrong:
  set_names(function(x) class(x) |> paste(collapse = ", "))
#> $character
#> # A tibble: 2 × 10
#>   carat cut   color clarity depth table price     x     y     z
#>   <dbl> <ord> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
#> 1  0.22 Fair  E     VS2      65.1    61   337  3.87  3.78  2.49
#> 2  0.86 Fair  E     SI2      55.1    69  2757  6.45  6.33  3.52
#> 
#> $character
#> # A tibble: 2 × 10
#>   carat cut   color clarity depth table price     x     y     z
#>   <dbl> <ord> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
#> 1  0.23 Good  E     VS1      56.9    65   327  4.05  4.07  2.31
#> 2  0.31 Good  J     SI2      63.3    58   335  4.34  4.35  2.75


# Evidence that each element should be named "tbl_df, tbl, data.frame", not character
l1[[1]] |> 
  class() |> 
  paste(collapse = ", ")
#> [1] "tbl_df, tbl, data.frame"

Created on 2025-03-13 with reprex v2.1.1


Solution

  • The issue is that R is not passing each element of l1 to your function - it's passing the names of the elements. But your list doesn't have names yet -> R is creating temporary names which are of type "character", and that's what's being passed to your function. there might be better ways, but you can try

    library(tidyverse)
    l1 <- diamonds |> group_split(cut) |> map(~ .x |> slice(1:2)) |> head(2)
    
    setNames(l1, map_chr(l1, ~paste(class(.x), collapse = ", ")))
    
    $`tbl_df, tbl, data.frame`
    # A tibble: 2 × 10
      carat cut   color clarity depth table price     x     y     z
      <dbl> <ord> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
    1  0.22 Fair  E     VS2      65.1    61   337  3.87  3.78  2.49
    2  0.86 Fair  E     SI2      55.1    69  2757  6.45  6.33  3.52
    
    $`tbl_df, tbl, data.frame`
    # A tibble: 2 × 10
      carat cut   color clarity depth table price     x     y     z
      <dbl> <ord> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
    1  0.23 Good  E     VS1      56.9    65   327  4.05  4.07  2.31
    2  0.31 Good  J     SI2      63.3    58   335  4.34  4.35  2.75